emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [BUG] wrong side of point [9.7.13 (9.7.13-8566bc @ /Users/jaydixit/.emacs.d/elpa/develop/org-9.7.13/)]
@ 2024-10-24 16:00 10% Jay Dixit
  0 siblings, 0 replies; 200+ results
From: Jay Dixit @ 2024-10-24 16:00 UTC (permalink / raw)
  To: org-mode org

[-- Attachment #1: Type: text/plain, Size: 106915 bytes --]

Emacs  : GNU Emacs 29.1 (build 1, aarch64-apple-darwin23.6.0, Carbon
Version 170 AppKit 2487.7)
 of 2024-08-22
Package: Org mode version 9.7.13 (9.7.13-8566bc @
/Users/jaydixit/.emacs.d/elpa/develop/org-9.7.13/)

current state:
==============
(setq
 org-agenda-prefix-format '((agenda .
                             " %?-12t% s")
                            (timeline . "  % s")
                            (todo . " %i %-12:c")
                            (tags . " %i %-12:c")
                            (search .
                             " %i %-12:c")
                            )
 org-archive-location "archive/%s_archive::"
 org-roam-db-location "/Users/jay/dropbox/roam/org-roam.db"
 org-link-elisp-confirm-function 'yes-or-no-p
 org-hierarchical-todo-statistics nil
 org-directory "~/Dropbox/writing/notationaldata/"
 org-hide-emphasis-markers t
 org-bibtex-headline-format-function 'org-bibtex-headline-format-default
 org-yank-adjusted-subtrees t
 org-twbs-htmlize-output-type 'css
 org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
org-attach-id-uuid-folder-format)
 org-roam-dailies-capture-templates '(("j"
                                       "default"
                                       entry
                                       "* %?"
                                       :target
                                       (file+head
                                        "%<%Y-%m-%d>.org" "#+TITLE:
%<%Y-%m-%d>\n#+FILETAGS: :journal:\n- Links :: \n\n* %<%A, %B %d,
%Y>\n\n\n** Today [0/1]\n")
                                       )
                                      )
 org-agenda-custom-commands '(("r" "Review items"
                               agenda ""
                               ((org-agenda-skip-function
                                 '(org-agenda-skip-entry-if 'notregexp
"::review::")
                                 )
                                (org-agenda-prefix-format " %i
%-12:c%?-12t% s")
                                (org-agenda-overriding-header "Items to
review")
                                )
                               )
                              ("n"
                               "Agenda and all TODOs"
                               ((agenda "")

                                                       (alltodo "")

                                                       )
                               )
                              )
 org-twbs-format-drawer-function '(lambda
                                   (name contents)
                                   contents)
 org-startup-folded nil
 org-babel-after-execute-hook '(spacemacs/ob-fix-inline-images)
 org-startup-align-all-tables t
 org-roam-node-display-template #("${title:*} ${tags:15}" 11 21 (face
org-tag))
 org-indent-mode-turns-on-hiding-stars nil
 org-persist-after-read-hook '(org-element--cache-persist-after-read)
 org-latex-toc-command "\\tableofcontents\n\\newpage\n"
 org-refile-targets '((my-org-files-list
                       :maxlevel . 4)
                      )
 org-roam-file-exclude-regexp '("data/")
 org-export-before-parsing-hook '(org-export-id-link-removal
                                  (lambda

                                                              (backend)


(replace-regexp "^\\([A-Za-z]+:\\)\\([^/]\\|/[^/]\\|$\\)" "*\\1*\\2")

                                                              )
                                  org-attach-expand-links)
 org-clone-delete-id t
 org-cycle-tab-first-hook '(yas-org-very-safe-expand
org-babel-hide-result-toggle-maybe org-babel-header-arg-expand)
 org-tag-alist '(("important" . 105)
                 ("urgent" . 117))
 org-html-doctype "html5"
 org-default-notes-file "~/Dropbox/writing/notationaldata/notes.txt"
 org-export-async-init-file
"/Users/jaydixit/.emacs.d/layers/+emacs/org/local/org-async-init.el"
 org-roam-find-file-hook '(org-roam-buffer--setup-redisplay-h
org-roam--register-completion-functions-h
org-roam--replace-roam-links-on-save-h
org-roam-db-autosync--setup-update-on-save-h)
 org-refile-use-outline-path t
 org-publish-timestamp-directory "~/.emacs.d/.cache/.org-timestamps/"
 org-transclusion-after-add-functions
'(org-translusion-indent-add-properties)
 org-finalize-agenda-hook '((lambda nil
                             (remove-text-properties
                              (point-min)
                              (point-max)
                              '(mouse-face t))
                             )
                            )
 org-archive-hook '(my/org-archive-file
                    org-attach-archive-delete-maybe)
 org-html-postamble nil
 org-edit-src-content-indentation 4
 org-ascii-format-drawer-function #[771 " \207" [] 4 "\n\n(fn NAME CONTENTS
WIDTH)"]
 org-cycle-hook '(org-cycle-hide-archived-subtrees
org-cycle-show-empty-lines
org-cycle-optimize-window-after-visibility-change
org-cycle-display-inline-images)
 org-clocktable-defaults '(:maxlevel 3 :lang "en"
                           :scope file :block nil
                           :wstart 1 :mstart 1
                           :tstart nil :tend nil
                           :step nil :stepskip0
                           nil :fileskip0 nil
                           :tags nil :emphasize
                           nil :link nil :narrow
                           40! :indent t :formula
                           nil :timestamp nil
                           :level nil :tcolumns
                           nil :formatter nil)
 org-enforce-todo-checkbox-dependencies t
 org-export-with-clocks t
 org-persist-before-read-hook '(org-element--cache-persist-before-read)
 org-font-lock-set-keywords-hook '(org-transclusion-font-lock-set)
 org-cycle-emulate-tab nil
 org-twbs-preamble nil
 org-modules '(org-habit ol-doi ol-w3m ol-bbdb
               ol-bibtex ol-docview ol-gnus
               ol-info ol-irc ol-mhe ol-rmail
               ol-eww)
 org-yank-image-file-name-function 'org-yank-image-autogen-filename
 org-image-actual-width nil
 org-mode-hook '((lambda nil
                  (setq captain-predicate
                   #'(lambda nil t))
                  )
                 capitalist-mode-on
                 context-menu-mode
                 (lambda nil (redbold))
                 (lambda nil
                  (add-hook
                   'window-configuration-change-hook
'activate-olivetti-in-split nil t)
                  )
                 (lambda nil
                  (org-superstar-mode 1))
                 #[0 "\301\211 \207"
                   [imenu-create-index-function
                    org-imenu-get-tree]
                   2]
                 (lambda nil
                  (define-key org-mode-map
                   (kbd "DEL")
                   'new-org-delete-backward-char)
                  )
                 wrap-region-mode
                 (lambda nil (auto-fill-mode -1))
                 turn-on-visual-line-mode
                 flycheck-mode
                 (lambda nil
                  (flyspell-lazy-mode 1))
                 turn-on-flyspell dubcaps-mode
                 org-clock-load org-tempo-setup
                 (lambda nil
                  (make-variable-buffer-local
                   'yas--trigger-key)
                  (setq yas-trigger-key [tab])
                  (add-to-list
                   'org-tab-first-hook
                   'yas-org-very-safe-expand)
                  (define-key yas-keymap [tab]
                   'yas-next-field)
                  )
                 wc-mode hl-todo-mode
                 setup-org-mode-keys
                 #[0 "\300\301\302\303\304$\207"
                   [add-hook
                    change-major-mode-hook
                    org-fold-show-all append
                    local]
                   5]
                 #[0 "\300\301\302\303\304$\207"
                   [add-hook
                    change-major-mode-hook
                    org-babel-show-result-all
                    append local]
                   5]
                 org-babel-result-hide-spec
                 org-babel-hide-all-hashes
                 flyspell-mode
                 spacemacs/load-yasnippet
                 toc-org-enable
                 org-superstar-mode
                 dotspacemacs//prettify-spacemacs-docs)
 org-babel-load-languages '((python . t)
                            (emacs-lisp . t))
 org-src-window-setup 'current-window
 org-ctrl-k-protect-subtree t
 org-id-locations-file "~/.emacs.d/.cache/.org-id-locations"
 org-highlight-links '(bracket plain radio tag
                       date footnote)
 org-transclusion-include-first-section nil
 org-html-head "<style
type=\"text/css\">\n<!--/*--><![CDATA[/*><!--*/\nbody, p, h1, h2, h3, h4,
h5, h6, a, li, span, div {\n    font-family: \"Helvetica Neue\", Helvetica,
sans-serif !important;\n    font-size: 13px
!important;\n}\n/*]]>*/-->\n</style>\n"
 org-roam-ref-annotation-function 'org-roam-ref-read--annotation
 org-roam-directory "/Users/jaydixit/Dropbox/roam"
 org-twbs-format-inlinetask-function 'ignore
 org-export-allow-bind-keywords t
 org-latex-format-drawer-function '(closure
                                    (engrave-faces-latex-mathescape
engrave-faces-current-preset-style engrave-faces-latex-output-style t)
                                    (_ contents)
                                    contents)
 org-ellipsis " 🪜 "
 org-custom-properties '(">")
 org-roam-db-node-include-function #[0 "\300\207" [t] 1]
 org-export-exclude-tags '("noexport" "extra")
 org-latex-format-headline-function
'org-latex-format-headline-default-function
 org-confirm-shell-link-function 'yes-or-no-p
 org-present-mode-hook '(spacemacs//org-present-start)
 org-projectile-per-project-filepath "TODOs.org"
 org-export-with-section-numbers nil
 org-present-mode-quit-hook '(spacemacs//org-present-end)
 org-tempo-keywords-alist '(("l " .
                             "src emacs-lisp ")
                            ("H" . "html")
                            ("A" . "ascii")
                            ("i" . "index"))
 org-html-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME CONTENTS)"]
 outline-isearch-open-invisible-function 'outline-isearch-open-invisible
 org-roam-dailies-directory "journal/"
 org-startup-indented t
 org-export-before-processing-hook '(my-org-inline-css-hook)
 org-ascii-headline-spacing '(1 . 1)
 org-latex-classes '(("blue-invoice-letterhead"

"\n\n\\documentclass[12pt]{article}\n\\usepackage[includeheadfoot,margin=1.0in,hmargin=1.0in,vmargin=0.5in]{geometry}\n\\usepackage{float}\n\\usepackage{changepage}\n\n\\usepackage{algorithm}\n\\usepackage{amsmath}\n\\usepackage{ifxetex}\n\\ifxetex\n
 \\usepackage{fontspec,xltxtra,xunicode}\n
 \\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}\n\n\\usepackage{fontspec}\n\n%
define Helvetica Now font weights\n\\setmainfont{HelveticaNow}[\n  Path =
/Users/jay/Library/Fonts/,\n  UprightFont = HelveticaNowText-Light,\n
 BoldFont = HelveticaNowDisplay-Bold,\n  ItalicFont =
HelveticaNowText-LightItalic,\n  BoldItalicFont =
HelveticaNowDisplay-BoldIta,\n  Extension =
.ttf\n]\n\n\\setromanfont{HelveticaNowText-Light}\n\\setsansfont{HelveticaNowDisplay-Regular}\n\n%
define sans font\n\\setsansfont{Helvetica Neue LT Pro}[\n  Path =
/Users/jay/Library/Fonts/,\nUprightFont = HelveticaNeueLTPro-MdCn,\n
 BoldFont = HelveticaNeueLTPro-BdCn,\n  Extension =
.otf\n]\n\n\\newfontfamily{\\thindisplayfont}{HelveticaNowDisplay-Light}\n\\setmonofont{Myriad
Pro}\n\n\n\\usepackage{fancyhdr}\n\\pagestyle{fancy}\n\\renewcommand{\\headrulewidth}{0pt}
% Removes the default horizontal\n\n\\else\n
 \\usepackage[mathletters]{ucs}\n
 \\usepackage[utf8x]{inputenc}\n\\fi\n\\usepackage{url}\n\\usepackage{paralist}\n\\usepackage{graphicx}\n%\\usepackage{tikz}\n\\usepackage{calc}\n\\usepackage{eso-pic}\n\\usepackage{etoolbox}\n\\usepackage{xcolor}\n\\PassOptionsToPackage{hyperref,x11names}{xcolor}\n\\definecolor{pinterestred}{HTML}{C92228}\n\\definecolor{ulyssesbutterflyblue}{HTML}{1464F4}\n\\definecolor{signalflare}{HTML}{FB782C}\n\\definecolor{niceorange}{HTML}{77CC6D}\n\\definecolor{ghostlygrey}{HTML}{000000}\n\\definecolor{firstcolor}{HTML}{00ADEF}\n\\definecolor{secondcolor}{HTML}{DD3E74}\n\\definecolor{periodblue}{HTML}{12239e}\n\\definecolor{denimblue}{HTML}{3A5F90}\n\\definecolor{electricblue}{HTML}{05ADF3}\n\\definecolor{resonateblue}{HTML}{005778}\n\\definecolor{resonateorange}{HTML}{da7635}\n\\definecolor{resonategrey}{HTML}{4d4d4c}\n\\definecolor{nliblue}{HTML}{2f9ed3}\n\\definecolor{elegantblue}{HTML}{1792d1}\n\\definecolor{ideablue}{HTML}{55C1E7}\n\\definecolor{libertyblue}{HTML}{73b0be}\n\\definecolor{darklibertyblue}{HTML}{19455b}\n\n\n\\newtoks\\leftheader\n\\newtoks\\leftheaderurl\n\\newtoks\\coverimage\n\\newtoks\\rightheader\n\n\\raggedright\n\\hyphenpenalty=5000\n\\tolerance=1000\n\n\n\\renewcommand{\\contentsname}{Invoice}\n\n\n\n%This
macro is to make cleaner the specification of the titling
font\n\\newfontfamily\\mytitlefont[Color={libertyblue}]{Arial}\n\\newfontfamily\\myauthorfont[Color={libertyblue}]{Arial}\n\\newfontfamily\\mybluefont[Color=libertyblue]{Arial}\n\n%Define
Bold
face\n\\DeclareTextFontCommand{\\textbf}{\\sffamily\\bfseries}\n\\DeclareTextFontCommand{\\textit}{\\itshape}\n\n\\usepackage{textcase}\n\n\\pagenumbering{arabic}\n\\makeatletter\n\n\n\\setcounter{secnumdepth}{0}\n\n\n\\usepackage[labelformat=empty]{caption}\n\n\n\\usepackage{fancyhdr}\n\\pagestyle{fancy}\n\\renewcommand{\\headrulewidth}{0pt}
% Removes the default horizontal line in the header\n\n\n\\fancyhead[C]{%\n
 \\begin{minipage}[c][1in][c]{1\\linewidth}\n
 \\includegraphics[height=1in,keepaspectratio]{/Users/jay/Dropbox/github/
incandescentman.github.io/assets/images/2023-10-final-new-logo_high-res-no-text.png}\n
 \\end{minipage}%\n  \\hspace{0in} % Reducing space to 0 inches between the
logo and the text\n  \\begin{minipage}[c][1in][c]{0.3\\linewidth}\n
 \\raggedright % Left-align the text in the minipage\n
 \\raisebox{0.59in}[0pt][0pt]{ % Raise the text by 0.7 inches\n
 {\\fontsize{73}{82}\\sffamily\\color{darklibertyblue} STORYTELLING.NYC}\n
   }\n  \\end{minipage}%\n  \\hspace{2.7in} % Move the text 1 inch to the
left\n}\n\n\n\n\\rhead{}\n\\lfoot{}\n\\cfoot{}\n\\rfoot{}\n\n\n\\usepackage{listings}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{12pt
plus 2pt minus 1pt} % space between paragraphs\n\n% spacing: how to read
{12pt plus 4pt minus 2pt}\n%           12pt is what we would like the
spacing to be\n%           plus 4pt means that TeX can stretch it by at
most 4pt\n%           minus 2pt means that TeX can shrink it by at most
2pt\n%       This is one example of the concept of, 'glue', in
TeX\n\n\\usepackage{fancyvrb}\n\\usepackage{enumerate}\n\\usepackage{ctable}\n\\setlength{\\paperwidth}{8.5in}\n\\setlength{\\paperheight}{11in}\n
 \\tolerance=1000\n\\usepackage{tocloft}\n\\renewcommand{\\cftsecleader}{\\cftdotfill{\\cftdotsep}}\n\\usepackage[normalem]{ulem}\n\n\n\\makeatletter\n\\newcommand{\\globalcolor}[1]{%\n
 \\color{#1}\\global\\let\\default@color\\current@color\n}\n\\makeatother\n\n\\newcommand{\\textsubscr}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}\n\n\\usepackage{enumitem}\n\n\\newlist{mylist}{enumerate}{10}\n\n\n%
control line spacing in bulleted list\n\\setlist{noitemsep, topsep=-8pt,
after=\\vspace{12pt}} % for no spacing between list items\n% see:
https://tex.stackexchange.com/questions/199118/modifying-whitespace-before-and-after-list-separately-using-enumitem-package\n%\\setlist{topsep=0pt}
% for a line between list items\n\n\n\\renewcommand{\\labelitemi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemviii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemix}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemx}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\n\\setlistdepth{10}\n\\setlist[itemize,1]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,2]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,3]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,4]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,5]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,6]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,7]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,8]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,9]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,10]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\renewlist{itemize}{itemize}{10}\n\n\n\n\n\n\\definecolor{azure}{HTML}{f2feff}\n\n\\usepackage{lipsum}\n\\usepackage{tikz}\n\\usetikzlibrary{backgrounds}\n\\makeatletter\n\n\\tikzset{%\n
 fancy quotes/.style={\n    text width=\\fq@width pt,\n    align=justify,\n
   inner sep=1em,\n    anchor=north west,\n    minimum width=\\linewidth,\n
 },\n  fancy quotes width/.initial={.8\\linewidth},\n  fancy quotes
marks/.style={\n    scale=8,\n    text=black,\n    inner sep=0pt,\n  },\n
 fancy quotes opening/.style={\n    fancy quotes marks,\n  },\n  fancy
quotes closing/.style={\n    fancy quotes marks,\n  },\n  fancy quotes
background/.style={\n    show background rectangle,\n    inner frame
xsep=0pt,\n    background rectangle/.style={\n      fill=azure,\n
 rounded corners,\n    },\n
 }\n}\n\n\\newenvironment{fancyquotes}[1][]{%\n\\noindent\n\\tikzpicture[fancy
quotes background]\n\\node[fancy quotes opening,anchor=north west] (fq@ul)
at (0,0) {``};\n\\tikz@scan@one@point\\pgfutil@firstofone(fq@ul.east
)\n\\pgfmathsetmacro{\\fq@width}{\\linewidth - 2*\\pgf@x}\n\\node[fancy
quotes,#1] (fq@txt) at (fq@ul.north west)
\\bgroup}\n{\\egroup;\n\\node[overlay,fancy quotes closing,anchor=east] at
(fq@txt.south east)
{''};\n\\endtikzpicture}\n\\makeatother\n\n%\\setlength{\\intextsep}{10pt
plus 1.0pt minus 2.0pt}\n\n\\newenvironment{indentedsection}\n
 {\\adjustwidth{2em}{0pt}}\n
 {\\endadjustwidth}\n\n\n\\usepackage{setspace}\n\\usepackage{lipsum}\n\\usepackage{etoolbox}\n\\AtBeginEnvironment{quote}{\\singlespace\\vspace{-\\topsep}\\small}\n\\AtEndEnvironment{quote}{\\vspace{-\\topsep}\\endsinglespace}\n\n\n\\usepackage[sc]{titlesec}\n\n\n\\newlength\\TitleOverhang\n\\setlength\\TitleOverhang{1.5cm}\n\n\\newcommand\\Overhang[1]{%\n
\\llap{\\makebox[\\TitleOverhang][l]{#1}}%\n}\n\n\n%
\\titlespacing{command}{left spacing}{before spacing}{after
spacing}[right]\n\\titlespacing*{\\section}{0pt}{24pt}{-6pt}\n\\titlespacing*{\\subsection}{0pt}{16pt}{-6pt}\n\\titlespacing*{\\subsubsection}{0pt}{6pt}{-6pt}\n\n\n\\titleformat*{\\section}{\\sffamily\\bfseries\\fontsize{30}{20}\\raggedright\\sffamily\\scshape\\color{libertyblue}}\n\\titleformat*{\\subsection}{\\sffamily\\fontsize{18}{15}\\raggedright\\scshape\\color{libertyblue}}\n\\titleformat*{\\subsubsection}{\\sffamily\\bfseries\\fontsize{14}{16}\\raggedright\\sffamily\\color{libertyblue}}\n\\titleformat*{\\paragraph}{\\sffamily\\fontsize{13}{12}\\raggedright\\bfseries\\color{libertyblue}}\n\\titleformat*{\\subparagraph}{\\sffamily\\fontsize{14}{14}\\raggedright\\bfseries\\ttfamily\\color{libertyblue}}\n\n\n\\DeclareTextFontCommand{\\nonsection}{\\sffamily\\fontsize{19}{19}\\raggedright\\sffamily\\textlf\\color{libertyblue}
}\n\n\\DeclareTextFontCommand{\\nonsubsection}{\\sffamily\\fontsize{18}{15}\\raggedright\\scshape\\color{libertyblue}}\n\n\\DeclareTextFontCommand{\\nonsubsubsection}{\\sffamily\\itshape\\fontsize{14}{14}\\raggedright\\sffamily\\color{libertyblue}
}\n\n\n\\usepackage[breaklinks=true,linktocpage,xetex]{hyperref}\n\\hypersetup{colorlinks,
citecolor=libertyblue,filecolor=libertyblue,linkcolor=libertyblue,urlcolor=libertyblue}\n\n\\renewcommand\\maketitle{}\n\n\n
     [NO-DEFAULT-PACKAGES]\n      [NO-PACKAGES]"
                      ("\\section{%s}" .
                       "\\section*{%s}")
                      ("\\subsection{%s}" .
                       "\\subsection*{%s}")
                      ("\\subsubsection{%s}" .
                       "\\subsubsection*{%s}")
                      ("\\paragraph{%s}" .
                       "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" .
                       "\\subparagraph*{%s}")
                      )
                     ("blue-invoice"

"\n\n\\documentclass[12pt]{article}\n\\usepackage[includeheadfoot,margin=1.0in,hmargin=1.0in,vmargin=0.5in]{geometry}\n\\usepackage{float}\n\\usepackage{changepage}\n\n\\usepackage{algorithm}\n\\usepackage{amsmath}\n\\usepackage{ifxetex}\n\\ifxetex\n
 \\usepackage{fontspec,xltxtra,xunicode}\n
 \\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}\n\n\n% define
Helvetica Now font weights\n\\setmainfont{EBGaramond}[\n  Path =
/Users/jay/Library/Fonts/,\n        UprightFont = HelveticaNowText-Light,\n
       BoldFont = HelveticaNowDisplay-Bold,\n        ItalicFont =
HelveticaNowText-LightItalic,\n        BoldItalicFont =
HelveticaNowDisplay-BoldIta,\n  Extension =
.ttf\n\n\\setromanfont{HelveticaNowText-Light}\n\\setsansfont{HelveticaNowDisplay-Regular}\n\\newfontfamily{\\thindisplayfont}{HelveticaNowDisplay-Light}\n\\setmonofont{Myriad
Pro}\n\\else\n  \\usepackage[mathletters]{ucs}\n
 \\usepackage[utf8x]{inputenc}\n\\fi\n\\usepackage{url}\n\\usepackage{paralist}\n\\usepackage{graphicx}\n\\setkeys{Gin}{resolution=72}\n\\usepackage{tikz}\n\\usepackage{calc}\n\\usepackage{eso-pic}\n\\usepackage{etoolbox}\n\\usepackage{xcolor}\n\\PassOptionsToPackage{hyperref,x11names}{xcolor}\n\\definecolor{pinterestred}{HTML}{C92228}\n\\definecolor{ulyssesbutterflyblue}{HTML}{1464F4}\n\\definecolor{signalflare}{HTML}{FB782C}\n\\definecolor{niceorange}{HTML}{77CC6D}\n\\definecolor{ghostlygrey}{HTML}{000000}\n\\definecolor{firstcolor}{HTML}{00ADEF}\n\\definecolor{secondcolor}{HTML}{DD3E74}\n\\definecolor{periodblue}{HTML}{12239e}\n\\definecolor{denimblue}{HTML}{3A5F90}\n\\definecolor{electricblue}{HTML}{05ADF3}\n\\definecolor{resonateblue}{HTML}{005778}\n\\definecolor{resonateorange}{HTML}{da7635}\n\\definecolor{resonategrey}{HTML}{4d4d4c}\n\\definecolor{nliblue}{HTML}{2f9ed3}\n\\definecolor{elegantblue}{HTML}{1792d1}\n\\definecolor{ideablue}{HTML}{55C1E7}\n\\definecolor{libertyblue}{HTML}{73b0be}\n\n\n\\newtoks\\leftheader\n\\newtoks\\leftheaderurl\n\\newtoks\\coverimage\n\\newtoks\\rightheader\n\n\\raggedright\n\\hyphenpenalty=5000\n\\tolerance=1000\n\n\n\\renewcommand{\\contentsname}{Invoice}\n\n\n\n%This
macro is to make cleaner the specification of the titling
font\n\\newfontfamily\\mytitlefont[Color={highlighteryellow}]{Arial}\n\\newfontfamily\\myauthorfont[Color={highlighteryellow}]{Arial}\n\\newfontfamily\\mybluefont[Color=libertyblue]{Arial}\n\n%Define
Bold
face\n\\DeclareTextFontCommand{\\textbf}{\\sffamily\\bfseries}\n\\DeclareTextFontCommand{\\textit}{\\itshape}\n\n\\usepackage{textcase}\n\n\\pagenumbering{arabic}\n\\makeatletter\n\n\n\\setcounter{secnumdepth}{0}\n\n\n\\usepackage[labelformat=empty]{caption}\n\n\\usepackage{fancyhdr}\n\\pagestyle{fancy}\n\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}\n\\lhead{\\href{\\the\\leftheaderurl}{\\the\\leftheader}}\n\\chead{}\n\\rhead{Invoice:
\\@title\\
 {\\nouppercase{\\the\\rightheader}}}\n\\lfoot{}\n\\cfoot{}\n\\rfoot{}\n\n\n\n\n\\usepackage{listings}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{12pt
plus 2pt minus 1pt} % space between paragraphs\n\n% spacing: how to read
{12pt plus 4pt minus 2pt}\n%           12pt is what we would like the
spacing to be\n%           plus 4pt means that TeX can stretch it by at
most 4pt\n%           minus 2pt means that TeX can shrink it by at most
2pt\n%       This is one example of the concept of, 'glue', in
TeX\n\n\\usepackage{fancyvrb}\n\\usepackage{enumerate}\n\\usepackage{ctable}\n\\setlength{\\paperwidth}{8.5in}\n\\setlength{\\paperheight}{11in}\n
 \\tolerance=1000\n\\usepackage{tocloft}\n\\renewcommand{\\cftsecleader}{\\cftdotfill{\\cftdotsep}}\n\\usepackage[normalem]{ulem}\n\n\n\\makeatletter\n\\newcommand{\\globalcolor}[1]{%\n
 \\color{#1}\\global\\let\\default@color\\current@color\n}\n\\makeatother\n\n\\newcommand{\\textsubscr}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}\n\n\\usepackage{enumitem}\n\n\\newlist{mylist}{enumerate}{10}\n\n\n%
control line spacing in bulleted list\n\\setlist{noitemsep, topsep=-8pt,
after=\\vspace{12pt}} % for no spacing between list items\n% see:
https://tex.stackexchange.com/questions/199118/modifying-whitespace-before-and-after-list-separately-using-enumitem-package\n%\\setlist{topsep=0pt}
% for a line between list items\n\n\n\\renewcommand{\\labelitemi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemviii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemix}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemx}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\n\\setlistdepth{10}\n\\setlist[itemize,1]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,2]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,3]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,4]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,5]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,6]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,7]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,8]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,9]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,10]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\renewlist{itemize}{itemize}{10}\n\n\n\n\n\n\\definecolor{azure}{HTML}{f2feff}\n\n\\usepackage{lipsum}\n\\usepackage{tikz}\n\\usetikzlibrary{backgrounds}\n\\makeatletter\n\n\\tikzset{%\n
 fancy quotes/.style={\n    text width=\\fq@width pt,\n    align=justify,\n
   inner sep=1em,\n    anchor=north west,\n    minimum width=\\linewidth,\n
 },\n  fancy quotes width/.initial={.8\\linewidth},\n  fancy quotes
marks/.style={\n    scale=8,\n    text=black,\n    inner sep=0pt,\n  },\n
 fancy quotes opening/.style={\n    fancy quotes marks,\n  },\n  fancy
quotes closing/.style={\n    fancy quotes marks,\n  },\n  fancy quotes
background/.style={\n    show background rectangle,\n    inner frame
xsep=0pt,\n    background rectangle/.style={\n      fill=azure,\n
 rounded corners,\n    },\n
 }\n}\n\n\\newenvironment{fancyquotes}[1][]{%\n\\noindent\n\\tikzpicture[fancy
quotes background]\n\\node[fancy quotes opening,anchor=north west] (fq@ul)
at (0,0) {``};\n\\tikz@scan@one@point\\pgfutil@firstofone(fq@ul.east
)\n\\pgfmathsetmacro{\\fq@width}{\\linewidth - 2*\\pgf@x}\n\\node[fancy
quotes,#1] (fq@txt) at (fq@ul.north west)
\\bgroup}\n{\\egroup;\n\\node[overlay,fancy quotes closing,anchor=east] at
(fq@txt.south east)
{''};\n\\endtikzpicture}\n\\makeatother\n\n%\\setlength{\\intextsep}{10pt
plus 1.0pt minus 2.0pt}\n\n\\newenvironment{indentedsection}\n
 {\\adjustwidth{2em}{0pt}}\n
 {\\endadjustwidth}\n\n\n\\usepackage{setspace}\n\\usepackage{lipsum}\n\\usepackage{etoolbox}\n\\AtBeginEnvironment{quote}{\\singlespace\\vspace{-\\topsep}\\small}\n\\AtEndEnvironment{quote}{\\vspace{-\\topsep}\\endsinglespace}\n\n\n\\usepackage[sc]{titlesec}\n\n\n\\newlength\\TitleOverhang\n\\setlength\\TitleOverhang{1.5cm}\n\n\\newcommand\\Overhang[1]{%\n
\\llap{\\makebox[\\TitleOverhang][l]{#1}}%\n}\n\n\n%
\\titlespacing{command}{left spacing}{before spacing}{after
spacing}[right]\n\\titlespacing*{\\section}{0pt}{16pt}{-6pt}\n\\titlespacing*{\\subsection}{0pt}{16pt}{-6pt}\n\\titlespacing*{\\subsubsection}{0pt}{6pt}{-6pt}\n\n\n\\titleformat*{\\section}{\\sffamily\\bfseries\\fontsize{30}{20}\\raggedright\\sffamily\\scshape\\color{libertyblue}}\n\\titleformat*{\\subsection}{\\sffamily\\fontsize{18}{15}\\raggedright\\scshape\\color{libertyblue}}\n\\titleformat*{\\subsubsection}{\\sffamily\\bfseries\\fontsize{14}{16}\\raggedright\\sffamily\\color{libertyblue}}\n\\titleformat*{\\paragraph}{\\sffamily\\fontsize{13}{12}\\raggedright\\bfseries\\color{libertyblue}}\n\\titleformat*{\\subparagraph}{\\sffamily\\fontsize{14}{14}\\raggedright\\bfseries\\ttfamily\\color{libertyblue}}\n\n\n\\DeclareTextFontCommand{\\nonsection}{\\sffamily\\fontsize{19}{19}\\raggedright\\sffamily\\textlf\\color{libertyblue}
}\n\n\\DeclareTextFontCommand{\\nonsubsection}{\\sffamily\\fontsize{18}{15}\\raggedright\\scshape\\color{libertyblue}}\n\n\\DeclareTextFontCommand{\\nonsubsubsection}{\\sffamily\\itshape\\fontsize{14}{14}\\raggedright\\sffamily\\color{libertyblue}
}\n\n\n\\usepackage[breaklinks=true,linktocpage,xetex]{hyperref}\n\\hypersetup{colorlinks,
citecolor=libertyblue,filecolor=libertyblue,linkcolor=libertyblue,urlcolor=libertyblue}\n\n\\renewcommand\\maketitle{}\n\n\n
     [NO-DEFAULT-PACKAGES]\n      [NO-PACKAGES]"
                      ("\\section{%s}" .
                       "\\section*{%s}")
                      ("\\subsection{%s}" .
                       "\\subsection*{%s}")
                      ("\\subsubsection{%s}" .
                       "\\subsubsection*{%s}")
                      ("\\paragraph{%s}" .
                       "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" .
                       "\\subparagraph*{%s}")
                      )
                     ("elegant-garamond"

"\n\\documentclass[12pt]{article}\n\\usepackage[includeheadfoot,
margin=1.5in, hmargin=1.5in, vmargin=0.5in]{geometry} % Set margins\n\n%
Package Inclusions\n\\usepackage{wrapfig}\n\\usepackage{float} % For
precise figure
placement\n\\usepackage{changepage}\n\\usepackage{algorithm}\n\\usepackage{pdfpages}\n\\usepackage{amsmath}\n\\usepackage{ifxetex}\n\\usepackage{setspace}\n\\usepackage{url}\n\\usepackage{paralist}\n\\usepackage{tikz}\n\\usepackage{calc}\n\\usepackage{eso-pic}\n\\usepackage{etoolbox}\n\\usepackage{xcolor}\n\\usepackage{microtype}
% Improve typography\n\\usepackage{booktabs} % Professional-looking
tables\n\\usepackage{fancyhdr} % Custom headers and
footers\n\\usepackage{xspace} % Consistent spacing after
commands\n\\usepackage{listings}\n\\usepackage{fancyvrb}\n\\usepackage{enumerate}\n\\usepackage{ctable}\n\\usepackage{tocloft}\n\\usepackage[normalem]{ulem}\n\\usepackage{enumitem}\n\\usepackage{titlesec}\n\\usepackage{lipsum}\n\\usepackage[breaklinks=true,
linktocpage, xetex]{hyperref}\n\\usepackage[most]{tcolorbox} % For enhanced
environments\n\n\\newcounter{level} % Define the custom
counter\n\\usepackage{forloop}\n\n\\setlength{\\headheight}{14.49998pt}\n\n%
Font Settings\n\\ifxetex\n  \\usepackage{fontspec}\n
 \\defaultfontfeatures{Mapping=tex-text, Scale=MatchLowercase}\n
 \\setsansfont{TeX Gyre Pagella}\n\n  % Set main font to Garamond Premier
Pro\n  \\setromanfont[\n    Path = /Users/jay/Library/Fonts/,\n
 UprightFont = GaramondPremrPro,\n    ItalicFont = GaramondPremrPro-It,\n
 BoldFont = GaramondPremrPro-Bd,\n    BoldItalicFont =
GaramondPremrPro-BdIt,\n    Extension = .otf\n  ]{Garamond Premier Pro}\n\n
 % Set monospaced font to Helvetica Neue LT Pro\n  \\setmonofont[\n    Path
= /Users/jay/Library/Fonts/,\n    UprightFont = HelveticaNeueLTPro-MdCn,\n
   BoldFont = HelveticaNeueLTPro-BdCn,\n    Extension = .otf\n  ]{Helvetica
Neue LT Pro}\n\\else\n  \\usepackage[mathletters]{ucs}\n
 \\usepackage[utf8x]{inputenc}\n\\fi\n\n% Color
Definitions\n\\definecolor{pinterestred}{HTML}{C92228}\n\\definecolor{ulyssesbutterflyblue}{HTML}{1464F4}\n\\definecolor{signalflare}{HTML}{FB782C}\n\\definecolor{niceorange}{HTML}{77CC6D}\n\\definecolor{highlighteryellow}{HTML}{FFFF01}\n\\definecolor{ghostlygrey}{HTML}{000000}\n\\definecolor{firstcolor}{HTML}{00ADEF}\n\\definecolor{secondcolor}{HTML}{DD3E74}\n\\definecolor{periodblue}{HTML}{12239e}\n\\definecolor{denimblue}{HTML}{3A5F90}\n\\definecolor{electricblue}{HTML}{05ADF3}\n\\definecolor{resonateblue}{HTML}{005778}\n\\definecolor{resonateorange}{HTML}{da7635}\n\\definecolor{resonategrey}{HTML}{4d4d4c}\n\\definecolor{nliblue}{HTML}{2f9ed3}\n\\definecolor{elegantblue}{HTML}{4380b9}\n\\definecolor{spacegrey}{HTML}{434346}\n\\definecolor{azure}{HTML}{f2feff}\n\n\\usepackage{enumitem}
% Ensures advanced list
customization\n\\newcommand{\\labelitemv}{\\textbullet}\n\\newcommand{\\labelitemvi}{\\textbullet}\n\\newcommand{\\labelitemvii}{\\textbullet}\n\\newcommand{\\labelitemviii}{\\textbullet}\n\\newcommand{\\labelitemix}{\\textbullet}\n\\newcommand{\\labelitemx}{\\textbullet}\n\n%
Header and Footer Configuration\n\\fancyhf{} % Clear all header and footer
fields\n\\renewcommand{\\headrulewidth}{0pt}\n\\pagestyle{fancy}\n\\newtoks\\leftheader\n\\newtoks\\leftheaderurl\n\\newtoks\\coverimage\n\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}\n\\lhead{\\scshape\\href{\\the\\leftheaderurl}{\\the\\leftheader}}\n\\rhead{\\scshape{\\leftmark}}\n\\cfoot{\\thepage}\n\n%
Paragraph and Indentation
Settings\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{12pt plus
2pt minus 1pt} % Space between
paragraphs\n\\onehalfspacing\n\\setstretch{1.2}\n\n% Table of Contents
Customization\n\\renewcommand{\\contentsname}{Table of
Contents}\n\\renewcommand{\\cftsecleader}{\\cftdotfill{\\cftdotsep}}\n\n%
Description Environment
Customization\n\\renewcommand{\\descriptionlabel}[1]{%\n
 {\\hspace{\\labelsep}\\bfseries\\textsc{#1}}}\n\\setlist[description]{style=nextline,
before=\\vspace{\\baselineskip}}\n\n% List Environment
Customization\n\\setlist{noitemsep, topsep=-8pt, after=\\vspace{12pt}} %
Control spacing in lists\n\\setlistdepth{10}\n\n% Define a Custom Raised
Bullet
Command\n\\newcommand{\\raisedtinybullet}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\n%
Redefine Itemize Labels Using the Custom
Bullet\n\\renewcommand{\\labelitemi}{\\raisedtinybullet}\n\\renewcommand{\\labelitemii}{\\raisedtinybullet}\n\\renewcommand{\\labelitemiii}{\\raisedtinybullet}\n\\renewcommand{\\labelitemiv}{\\raisedtinybullet}\n\\renewcommand{\\labelitemv}{\\raisedtinybullet}\n\\renewcommand{\\labelitemvi}{\\raisedtinybullet}\n\\renewcommand{\\labelitemvii}{\\raisedtinybullet}\n\\renewcommand{\\labelitemviii}{\\raisedtinybullet}\n\\renewcommand{\\labelitemix}{\\raisedtinybullet}\n\\renewcommand{\\labelitemx}{\\raisedtinybullet}\n\n%
Apply the Custom Bullet to All Itemize
Levels\n\\forloop{level}{1}{\\value{level} <= 10}{%\n
 \\setlist[itemize,\\arabic{level}]{label=\\raisedtinybullet}\n}\n\n% Quote
Environment Customization Using tcolorbox\n\\tcbset{\n  myquote/.style={\n
   colback=azure,\n    colframe=spacegrey,\n    colupper=black,\n
 boxrule=0.5pt,\n    rounded corners,\n
 fontupper=\\singlespacing\\fontsize{9}{11}\\selectfont\\ttfamily,\n
 width=0.8\\textwidth,\n    left=0pt,\n    right=0pt,\n
 boxalign=center,\n    halign=flush left,\n    before skip=1em,\n    after
skip=1em,\n    parskip=1em\n  }\n}\n\n\\renewenvironment{quote}\n{%\n
 \\begin{tcolorbox}[myquote]\n}\n{%\n  \\end{tcolorbox}\n}\n\n% Titlesec
Configuration\n\\titlespacing*{\\section}{0pt}{48pt}{0pt}\n\\titlespacing*{\\subsubsection}{0pt}{16pt}{0pt}\n\\titlespacing{\\paragraph}{0pt}{0pt}{.5em}[]\n\n\\newcommand{\\mysectiontitle}[1]{%\n
 \\raggedright\\fontsize{40}{26}\\selectfont
#1\n}\n\n\\titleformat{\\section}\n
 {\\normalfont\\ttfamily\\scshape\\color{spacegrey}}\n  {}\n  {0em}\n
 {\\mysectiontitle}\n\n\\titleformat*{\\subsection}{\\sffamily\\setstretch{0.1}\\fontsize{24}{36}\\raggedright\\sffamily}\n\\titleformat*{\\subsubsection}{\\ttfamily\\bfseries\\scshape\\fontsize{18}{16}\\raggedright\\ttfamily\\color{spacegrey}}\n\\titleformat*{\\paragraph}{\\ttfamily\\bfseries\\fontsize{19}{12}\\raggedright}\n\\titleformat*{\\subparagraph}{\\sffamily\\fontsize{16}{12}\\raggedright\\ttfamily\\bfseries}\n\n%
Hyperref Configuration\n\\hypersetup{\n  colorlinks,\n  citecolor =
elegantblue,\n  filecolor = elegantblue,\n  linkcolor = elegantblue,\n
 urlcolor  = elegantblue\n}\n\n% Disable Default
Title\n\\renewcommand\\maketitle{}\n\n[NO-DEFAULT-PACKAGES]\n[NO-PACKAGES]"
                      ("\\section{%s}" .
                       "\\section*{%s}")
                      ("\\subsection{%s}" .
                       "\\subsection*{%s}")
                      ("\\subsubsection{%s}" .
                       "\\subsubsection*{%s}")
                      ("\\paragraph{%s}" .
                       "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" .
                       "\\subparagraph*{%s}")
                      )
                     ("beautiful-racket"

"\n\n\\documentclass[12pt]{article}\n\\usepackage[includeheadfoot,margin=1.5in,hmargin=1.5in,vmargin=0.5in]{geometry}
% for normal margins\n\n% Use the geometry package to customize the page
layout, margins, and other aspects of your document's
appearance\n\n\n\\usepackage{wrapfig}\n\n\n% To have more control over
figure placement in your document, use the float package and its [H] option
to place figures exactly where you want them in the
text:\n\\usepackage{float}\n\n\n% \\usepackage{glossaries}\n%
\\makeglossaries\n\n\\usepackage{todonotes}\n%
\\usepackage[asterism]{sectionbreak}\n%
\\sectionbreakmark{❦}\n\n\n\\usepackage{wrapfig}\n\\usepackage{changepage}\n\\usepackage{algorithm}\n\\usepackage{pdfpages}\n\\usepackage{amsmath}\n\\usepackage{ifxetex}\n\\usepackage{setspace}\n\\ifxetex\n\\usepackage{fontspec,xltxtra,xunicode}\n\\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}\n\\setromanfont{Garamond
Premier Pro}\n \\setsansfont{TeX Gyre Pagella}\n  \\setmonofont{TeX Gyre
Heros}\n\n\\else\n  \\usepackage[mathletters]{ucs}\n
 \\usepackage[utf8x]{inputenc}\n\\fi\n\\usepackage{url}\n\\usepackage{paralist}\n\\usepackage{tikz}\n\\usepackage{calc}\n\\usepackage{eso-pic}\n\\usepackage{etoolbox}\n\\usepackage{xcolor}\n\\PassOptionsToPackage{hyperref,x11names}{xcolor}\n\\definecolor{pinterestred}{HTML}{C92228}\n\\definecolor{ulyssesbutterflyblue}{HTML}{1464F4}\n\\definecolor{signalflare}{HTML}{FB782C}\n\\definecolor{niceorange}{HTML}{77CC6D}\n\\definecolor{highlighteryellow}{HTML}{FFFF01}\n\\definecolor{ghostlygrey}{HTML}{000000}\n\\definecolor{firstcolor}{HTML}{00ADEF}\n\\definecolor{secondcolor}{HTML}{DD3E74}\n\\definecolor{periodblue}{HTML}{12239e}\n\\definecolor{denimblue}{HTML}{3A5F90}\n\\definecolor{electricblue}{HTML}{05ADF3}\n\\definecolor{resonateblue}{HTML}{005778}\n\\definecolor{resonateorange}{HTML}{da7635}\n\\definecolor{resonategrey}{HTML}{4d4d4c}\n\\definecolor{nliblue}{HTML}{2f9ed3}\n\\definecolor{elegantblue}{HTML}{4380b9}\n\\definecolor{spacegrey}{HTML}{434346}\n\n\\newtoks\\leftheader\n\\newtoks\\leftheaderurl\n\\newtoks\\coverimage\n\n\n\\setlength{\\marginparwidth}{2cm}
% Set marginparwidth for todonotes\n\n% \\usepackage{magaz}\n\n\n%Define
Bold
face\n\\DeclareTextFontCommand{\\textbf}{\\sffamily\\bfseries}\n\\DeclareTextFontCommand{\\textit}{\\itshape}\n\n\\usepackage{microtype}
%  Improve the overall typography and appearance of your document by
enabling micro-typographic features, such as character protrusion and font
expansion:\n\n\n\\hyphenpenalty=1000\n\\tolerance=1000\n\\exhyphenpenalty=100\n\\pretolerance=150\n\\emergencystretch=10pt\n\n\n\n\\pagenumbering{arabic}\n\\makeatletter\n\n\n\n\\setcounter{secnumdepth}{0}\n\n\n\\usepackage[font={small,tt}]{caption}\n\n\\usepackage{booktabs}
% Customized table styles: If you plan to use tables in your document, you
might want to consider customizing their appearance with the `booktabs`
package for professional-looking tables\n\n% Use the fancyhdr package to
customize the headers and footers of your document for a professional
appearance\n\n\\usepackage{fancyhdr}\n\\fancyhf{} % sets both header and
footer to
nothing\n\\renewcommand{\\headrulewidth}{0pt}\n\\pagestyle{fancy}\n\n\n\\setlength{\\headheight}{14.49998pt}
% Set headheight for
fancyhdr\n\n\n\n\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}\n\\lhead{\\scshape\\href{\\the\\leftheaderurl}{\\the\\leftheader}}\n\\chead{}\n\\rhead{{\\scshape{\\leftmark}}}
% Add section heading\n% \\rhead{\\@title:
{{\\leftmark}}}\n\\lfoot{}\n\\cfoot{\\thepage} % Add page
numbers\n\\rfoot{}\n\n\n% Ensure consistent spacing after periods in your
document by using the xspace
package:\n\\usepackage{xspace}\n\n\\newenvironment{fauxsubtitle}\n{\n\n\\Large\n\\itshape\n}\n\n\n\n\n\\usepackage{listings}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{12pt
plus 2pt minus 1pt} % space between paragraphs\n\n% spacing: how to read
{12pt plus 4pt minus 2pt}\n%           12pt is what we would like the
spacing to be\n%           plus 4pt means that TeX can stretch it by at
most 4pt\n%           minus 2pt means that TeX can shrink it by at most
2pt\n%       This is one example of the concept of, 'glue', in
TeX\n\n\n\\usepackage{setspace}\n\\onehalfspacing\n\\setstretch{1.2}\n\n\\usepackage{fancyvrb}\n\\usepackage{enumerate}\n\\usepackage{ctable}\n\\setlength{\\paperwidth}{8.5in}\n\\setlength{\\paperheight}{11in}\n\\usepackage{tocloft}\n\\renewcommand{\\cftsecleader}{\\cftdotfill{\\cftdotsep}}\n\\usepackage[normalem]{ulem}\n\n\n\\makeatletter\n\\newcommand{\\globalcolor}[1]{%\n
 \\color{#1}\\global\\let\\default@color\\current@color\n}\n\\makeatother\n\n\\newcommand{\\textsubscr}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}\n\n\\usepackage{enumitem}\n\n\\newlist{mylist}{enumerate}{10}\n\n\n%
control line spacing in bulleted list\n\\setlist{noitemsep, topsep=-8pt,
after=\\vspace{12pt}} % for no spacing between list items\n% see:
https://tex.stackexchange.com/questions/199118/modifying-whitespace-before-and-after-list-separately-using-enumitem-package\n%\\setlist{topsep=0pt}
% for a line between list items\n\n\n\\renewcommand{\\labelitemi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemviii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemix}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemx}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\n\\setlistdepth{10}\n\\setlist[itemize,1]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,2]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,3]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,4]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,5]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,6]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,7]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,8]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,9]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,10]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\renewlist{itemize}{itemize}{10}\n\n\n\\renewcommand{\\contentsname}{Table
of Contents}\n\n\n\n\\renewcommand{\\descriptionlabel}[1]{%\n
{\\hspace{\\labelsep}\\bfseries\\textsc{#1}}}\n\n\n\\setlist[description]{style=nextline,
before=\\vspace{\\baselineskip}}\n\n\n\\definecolor{azure}{HTML}{f2feff}\n\n\\usepackage{tikz}\n\\usetikzlibrary{backgrounds}\n\\makeatletter\n\n\\tikzset{%\n
 fancy quotes/.style={\n    text width=\\fq@width pt,\n    align=justify,\n
   inner sep=1em,\n    anchor=north west,\n    minimum width=\\linewidth,\n
 },\n  fancy quotes width/.initial={.8\\linewidth},\n  fancy quotes
marks/.style={\n    scale=8,\n    text=black,\n    inner sep=0pt,\n  },\n
 fancy quotes opening/.style={\n    fancy quotes marks,\n  },\n  fancy
quotes closing/.style={\n    fancy quotes marks,\n  },\n  fancy quotes
background/.style={\n    show background rectangle,\n    inner frame
xsep=0pt,\n    background rectangle/.style={\n      fill=azure,\n
 rounded corners,\n    },\n
 }\n}\n\n\\newenvironment{fancyquotes}[1][]{%\n\\noindent\n\\tikzpicture[fancy
quotes background]\n\\node[fancy quotes opening,anchor=north west] (fq@ul)
at (0,0) {``};\n\\tikz@scan@one@point\\pgfutil@firstofone(fq@ul.east
)\n\\pgfmathsetmacro{\\fq@width}{\\linewidth - 2*\\pgf@x}\n\\node[fancy
quotes,#1] (fq@txt) at (fq@ul.north west)
\\bgroup}\n{\\egroup;\n\\node[overlay,fancy quotes closing,anchor=east] at
(fq@txt.south east)
{''};\n\\endtikzpicture}\n\\makeatother\n\n%\\setlength{\\intextsep}{10pt
plus 1.0pt minus 2.0pt}\n\n\n\\newenvironment{indentedsection}\n{
 {\\adjustwidth{2em}{0pt}}\n
 {\\endadjustwidth}\n}\n\n\\usepackage{setspace}\n\\usepackage{lipsum}\n\\usepackage{etoolbox}\n\\AtBeginEnvironment{quote}{\\singlespace\\vspace{-\\topsep}\\small}\n\\AtEndEnvironment{quote}{\\vspace{-\\topsep}\\endsinglespace}\n\n\n\\usepackage[sc]{titlesec}\n\n\n\n\\newlength\\TitleOverhang\n\\setlength\\TitleOverhang{1.5cm}\n\n\\newcommand\\Overhang[1]{%\n
\\llap{\\makebox[\\TitleOverhang][l]{#1}}%\n}\n\n\n%
\\titlespacing{command}{left spacing}{before spacing}{after
spacing}[right]\n\\titlespacing*{\\section}{0pt}{150pt}{40pt}\n%\\titlespacing*{\\subsection}{0pt}{0pt}{-6pt}\n\\titlespacing*{\\subsubsection}{0pt}{16pt}{0pt}\n\n\\titlespacing{\\paragraph}{0pt}{0pt}{.5em}[]\n\n\\newcommand{\\mysectiontitle}[1]{%\n
 \\parbox{10cm}{\\raggedleft\\fontsize{40}{48}\\selectfont
#1}\n}\n\n\\usepackage{titlesec}\n\\usepackage{xcolor}\n\n\\titleformat{\\section}\n
 {\\normalfont\\ttfamily\\scshape\\color{spacegrey}}\n  {}\n  {0em}\n
 {\\hfill\\mysectiontitle}\n\n{\\raggedleft\\parbox[t]{10cm}{\\ttfamily\\scshape\\fontsize{40}{36}\\selectfont\\color{spacegrey}}}\n\n\n\\titleformat*{\\subsection}{\\sffamily\\setstretch{0.1}\\fontsize{24}{36}\\raggedright\\sffamily}\n\\titleformat*{\\subsubsection}{\\ttfamily\\scshape\\fontsize{18}{16}\\raggedright\\ttfamily}\\color{spacegrey}\n\n\\titleformat*{\\paragraph}{\\ttfamily\\bfseries\\fontsize{19}{12}\\raggedright}\n\\titleformat*{\\subparagraph}{\\sffamily\\fontsize{16}{12}\\raggedright\\ttfamily\\bfseries}\n\n\\DeclareTextFontCommand{\\nonsection}{\\sffamily\\fontsize{19}{19}\\raggedright\\sffamily\\textlf}\n\n\\DeclareTextFontCommand{\\nonsubsection}{\\sffamily\\itshape\\fontsize{18}\\raggedright\\sffamily}\n\n\\DeclareTextFontCommand{\\nonsubsubsection}{\\sffamily\\fontsize{18}\\raggedright\\sffamily}\n\n\n\\newenvironment{changemargin}[2]{%\n\\begin{list}{}{%\n\\setlength{\\topsep}{0pt}%\n\\setlength{\\leftmargin}{#1}%\n\\setlength{\\rightmargin}{#2}%\n\\setlength{\\listparindent}{\\parindent}%\n\\setlength{\\itemindent}{\\parindent}%\n\\setlength{\\parsep}{\\parskip}%\n}%\n\\item[]}{\\end{list}}\n\n\\newenvironment{tagline}%
environment name\n{% begin code\n  \\vspace{-36pt}\n  \\Large\n
 \\begin{changemargin}{1cm}{0cm} % Adjust these values as you see fit\n
 \\begin{itshape}%\n
 \\par\\vspace{\\baselineskip}\\noindent\\ignorespaces\n}%\n{% end code\n
 \\end{itshape}\\end{changemargin}\\vspace{24pt}\\ignorespacesafterend %
Close changemargin\n}\n\n\n\\newenvironment{fauxtitle}% environment
name\n{% begin code\n%\\vspace{12pt}\n\\Large\n\\begin{bfseries}%\n
 \\par\\vspace{\\baselineskip}\\noindent\\ignorespaces\n}%\n{% end code\n
 \\end{bfseries}\\vspace{12pt}\\ignorespacesafterend\n}\n\n\n\n\\newenvironment{fauxcenter}%
environment name\n{% begin code\n\n\\Large\n\\begin{center}\n\n}%\n{% end
code\n\\end{center}\\ignorespacesafterend\n}\n\n\n\n\n\\newenvironment{causationstatement}%
environment name\n{% begin
code\n\\vspace{-30pt}\n\\ttfamily\n\\bfseries\n\\begin{center}\n\n}%\n{%
end
code\n\\end{center}\\ignorespacesafterend\n}\n\n\n\n\n\n\n\\usepackage[breaklinks=true,linktocpage,xetex]{hyperref}\n\\hypersetup{colorlinks,
citecolor=elegantblue,filecolor=elegantblue,linkcolor=elegantblue,urlcolor=elegantblue}\n\n\\renewcommand\\maketitle{}\n\n\n\n
     [NO-DEFAULT-PACKAGES]\n      [NO-PACKAGES]"
                      ("\\section{%s}" .
                       "\\section*{%s}")
                      ("\\subsection{%s}" .
                       "\\subsection*{%s}")
                      ("\\subsubsection{%s}" .
                       "\\subsubsection*{%s}")
                      ("\\paragraph{%s}" .
                       "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" .
                       "\\subparagraph*{%s}")
                      )
                     ("elegant"

"\n\n\\documentclass[12pt]{article}\n\\usepackage{geometry}\n\n\\geometry{\n
 margin=1.5in, % Set all margins to 1.5 inches\n  bottom=1.5in, % Bottom
margin set to 1.25 inches\n  footskip=1.25in % Distance from the bottom of
the text area to the baseline of the
footer\n}\n\n\\usepackage{fontspec}\n\\linespread{1.2}\n\n\\usepackage[all]{nowidow}\n\n%\\usepackage{changepage}\n\n%\\usepackage{algorithm}\n%\\usepackage{amsmath}\n\n\n\n\\defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase}\n\n\n\n%
define Helvetica Now font weights\n\\setmainfont{HelveticaNow}[\n  Path =
/Users/jay/Library/Fonts/,\n  UprightFont = HelveticaNowText-Light,\n
 BoldFont = HelveticaNowDisplay-Bold,\n  ItalicFont =
HelveticaNowText-LightItalic,\n  BoldItalicFont =
HelveticaNowDisplay-BoldIta,\n  Extension =
.ttf\n]\n\n\\setromanfont{HelveticaNowText-Light}\n\\setsansfont{HelveticaNowDisplay-Regular}\n\n%
define sans font\n\\setsansfont{Helvetica Neue LT Pro}[\n  Path =
/Users/jay/Library/Fonts/,\nUprightFont = HelveticaNeueLTPro-MdCn,\n
 BoldFont = HelveticaNeueLTPro-BdCn,\n  Extension =
.otf\n]\n\n\\newfontfamily{\\thindisplayfont}{HelveticaNowDisplay-Light}\n\\setmonofont{Myriad
Pro} % for nice quotes\n% \\setmonofont{Adobe Garamond Pro} % for beautiful
LaTeX
Formulae\n\n\n%\\usepackage[mathletters]{ucs}\n%\\usepackage[utf8x]{inputenc}\n\n\n\\usepackage[obeyspaces]{url}\n\\PassOptionsToPackage{obeyspaces}{url}\n\n\\usepackage{paralist}\n\n\\usepackage{wrapfig}\n\\usepackage{setspace}\n%\\setkeys{Gin}{resolution=72}\n\\usepackage{tikz}\n\n%\\usepackage{calc}\n%\\usepackage{eso-pic}\n%\\usepackage{etoolbox}\n\\usepackage{xcolor}\n\\PassOptionsToPackage{hyperref,x11names}{xcolor}\n\\definecolor{pinterestred}{HTML}{C92228}\n\\definecolor{ulyssesbutterflyblue}{HTML}{1464F4}\n\\definecolor{signalflare}{HTML}{FB782C}\n\\definecolor{niceorange}{HTML}{77CC6D}\n\\definecolor{highlighteryellow}{HTML}{FFFF01}\n\\definecolor{ghostlygrey}{HTML}{000000}\n\\definecolor{firstcolor}{HTML}{00ADEF}\n\\definecolor{secondcolor}{HTML}{DD3E74}\n\\definecolor{periodblue}{HTML}{12239e}\n\\definecolor{denimblue}{HTML}{3A5F90}\n\\definecolor{electricblue}{HTML}{05ADF3}\n\\definecolor{resonateblue}{HTML}{005778}\n\\definecolor{resonateorange}{HTML}{da7635}\n\\definecolor{resonategrey}{HTML}{4d4d4c}\n\\definecolor{nliblue}{HTML}{2f9ed3}\n%\\definecolor{dullerelegantblue}{HTML}{4380b9}\n\\definecolor{elegantblue}{HTML}{1792d1}\n\\definecolor{ideablue}{HTML}{55C1E7}\n\\definecolor{powderblue}{HTML}{f5f7ff}\n\\definecolor{stormybluegrey}{HTML}{898ea4}\n\\definecolor{moonrockgrey}{HTML}{212121}\n\\definecolor{libertyblue}{HTML}{73b0be}\n\\definecolor{darklibertyblue}{HTML}{19455b}\n\n\n%
\\newtoks\\leftheader\n% \\newtoks\\leftheaderurl\n%
\\newtoks\\coverimage\n\n\\raggedright\n\\hyphenpenalty=5000\n\\tolerance=1000\n\n\\usepackage{textcase}\n\n\\pagenumbering{arabic}\n\\makeatletter\n\n\n\\renewcommand{\\contentsname}{Table
of
Contents}\n\n\\setcounter{secnumdepth}{0}\n\\usepackage{graphicx}\n\\usepackage{float}\n\n\n\\usepackage[labelformat=empty,
font=it,
width=0.9\\textwidth]{caption}\n\n\n\n\n\n%%%%%%%%%%%%%%%%%\n\n\\usepackage{fancyhdr}\n\\pagestyle{fancy}\n\\fancyhf{}\n\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}\n%
\\lhead{\\href{\\the\\leftheaderurl}{\\the\\leftheader}}\n\\chead{}\n\\rhead{{\\nouppercase{\\leftmark}}}\n%
\\rhead{\\@title:
{\\nouppercase{\\leftmark}}}\n\n\\lhead{\\bfseries\\@author} % title of the
document as left
header\n\n%\\renewcommand{\\footrulewidth}{0.4pt}\n\n\n\\fancyfoot[C]{%\n
 % Graphic\n  \\raisebox{0.025in}{% Increase this value to move the logo
higher\n%\\fontsize{43}{42}\\selectfont\\sffamily\\color{darklibertyblue}
STORYTELLING.NYC % large storytelling.NYC text
footer\n\n%\\includegraphics[height=0.4in,keepaspectratio]{/Users/jay/Dropbox/writing/prosperous/design/storytelling-nyc-logo/current-2018/_better-storytelling-nyc-canonical-helvetica-condensed-wide.png}
% The whole thing with NO period\n\n  }%\n  % Space between the graphic and
the text (adjust as needed)\n  %\\hspace{0.05in}%\n  % Text\n
 \\raisebox{1.05in}{% Adjust this value to align the text with the
image\n\n\n\n%
\\includegraphics[height=0.6in,keepaspectratio]{/Users/jay/Dropbox/writing/prosperous/design/storytelling-nyc-logo/current-2018/_better-storytelling-nyc-canonical-helvetica-condensed-wide.png}
% The whole thing\n\n%
\\includegraphics[height=0.8in,keepaspectratio]{/Users/jay/Dropbox/writing/prosperous/design/storytelling-nyc-logo/current-2018/_better-storytelling-nyc-period-canonical-helvetica-condensed.png}
% The whole thing with a
period\n\n%\\includegraphics[height=0.8in,keepaspectratio]{/Users/jay/Dropbox/writing/prosperous/design/storytelling-nyc-logo/current-2018/_better-storytelling-nyc-canonical-helvetica-condensed-wide.png}
% The whole thing with NO
period\n\n%\\includegraphics[height=0.6in,keepaspectratio]{/Users/jay/Dropbox/github/
incandescentman.github.io/assets/images/2023-10-final-new-logo_high-res-no-text.png}
% logo of just lady liberty\n  }%\n  % Space between the graphic and the
text (adjust as needed)\n  \\hspace{0.05in}%\n  % Text\n
 \\raisebox{0.35in}{% Adjust this value to align the text with the
image\n\n\n\n%\\fontsize{16}{16}\\sffamily\\color{black}All materials
Copyright Jay Dixit. % copyright\n\n\n\n  }%\n}\n\n% overwrite the logo
footer\n%\\cfoot{\\thepage} % Add page
numbers\n\n\n%%%%%%%%%%%%%%%%\n\n\\usepackage{listings}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{12pt
plus 2pt minus 1pt} % space between paragraphs\n\n% spacing: how to read
{12pt plus 4pt minus 2pt}\n%           12pt is what we would like the
spacing to be\n%           plus 4pt means that TeX can stretch it by at
most 4pt\n%           minus 2pt means that TeX can shrink it by at most
2pt\n%       This is one example of the concept of, 'glue', in
TeX\n\n%\\usepackage{fancyvrb}\n\\usepackage{enumerate}\n\\usepackage{ctable}\n\\setlength{\\paperwidth}{8.5in}\n\\setlength{\\paperheight}{11in}\n
 \\tolerance=1000\n\\usepackage{tocloft}\n\\renewcommand{\\cftsecfont}{\\normalfont}\n\\renewcommand{\\cftsecpagefont}{\\normalfont}\n\\renewcommand{\\cftsecleader}{\\cftdotfill{\\cftdotsep}}\n\\usepackage[normalem]{ulem}\n\n\n\n\\setlength{\\headheight}{15pt}
% Adjusted value based on warning\n\n\\addtolength{\\topmargin}{-3pt} %
Adjusted value to maintain
layout\n\n\n\\makeatletter\n\\newcommand{\\globalcolor}[1]{%\n
 \\color{#1}\\global\\let\\default@color\\current@color\n}\n\\makeatother\n\n\\newcommand{\\textsubscr}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}\n\n\\usepackage{enumitem}\n\\setlistdepth{10}
% Allows up to 10 levels of
nesting\n\n\\newlist{mylist}{enumerate}{10}\n\n\n% control line spacing in
bulleted list\n\\setlist{noitemsep, topsep=-8pt, after=\\vspace{12pt}} %
for no spacing between list items\n% see:
https://tex.stackexchange.com/questions/199118/modifying-whitespace-before-and-after-list-separately-using-enumitem-package\n%\\setlist{topsep=0pt}
% for a line between list items\n\n\n% Define labels for levels 5 to
10\n\\newcommand{\\labelitemv}{$\\bullet$}\n\\newcommand{\\labelitemvi}{$\\bullet$}\n\\newcommand{\\labelitemvii}{$\\bullet$}\n\\newcommand{\\labelitemviii}{$\\bullet$}\n\\newcommand{\\labelitemix}{$\\bullet$}\n\\newcommand{\\labelitemx}{$\\bullet$}\n\n\n\\renewcommand{\\labelitemi}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemii}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiii}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiv}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemv}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvi}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvii}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemviii}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemix}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemx}{\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\n\\setlistdepth{10}\n\\setlist[itemize,1]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,2]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,3]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,4]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,5]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,6]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,7]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,8]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,9]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\setlist[itemize,10]{label=\\raisebox{0.25ex}{\\tiny$\\bullet$}}\n\\renewlist{itemize}{itemize}{10}\n\n\n\\definecolor{azure}{HTML}{f2feff}\n\n%\\usepackage{lipsum}\n\n%\\setlength{\\intextsep}{10pt
plus 1.0pt minus 2.0pt}\n\n\\newenvironment{indentedsection}\n
 {\\adjustwidth{2em}{0pt}}\n
 {\\endadjustwidth}\n\n\n\n\\usepackage[most]{tcolorbox}\n\\usepackage{etoolbox}\n\n\\tcbuselibrary{skins}\n\n\\AtBeginEnvironment{quote}{\\vspace{1em}}\n\\AtEndEnvironment{quote}{\\vspace{1em}}\n\n\n\n\n\n\\usepackage[sc]{titlesec}\n\n\n\\newlength\\TitleOverhang\n\\setlength\\TitleOverhang{1.5cm}\n\n\\newcommand\\Overhang[1]{%\n
\\llap{\\makebox[\\TitleOverhang][l]{#1}}%\n}\n\n\n% Ensure the tcolorbox
package is included with the 'skins'
library\n\\usepackage[most]{tcolorbox}\n\n% Define custom colors if not
already
defined\n\\definecolor{powderblue}{HTML}{f5f7ff}\n\\definecolor{stormybluegrey}{HTML}{708090}\n\\definecolor{moonrockgrey}{HTML}{5D5D5D}\n\n%
Define a custom tcolorbox style for quotes\n\\tcbset{\n  myquote/.style={\n
   colback=powderblue,\n    colframe=stormybluegrey,\n
 colupper=moonrockgrey,\n    boxrule=0.5pt,\n    rounded corners,\n
 fontupper=\\singlespacing\\fontsize{9}{11}\\selectfont\\ttfamily,\n
 width=0.8\\textwidth,\n    left=0pt,\n    right=0pt,\n    halign=flush
left,\n    before skip=1em,  % Vertical space before the box\n    after
skip=1em,   % Vertical space after the box\n    parskip=1em       % Space
between paragraphs within the box\n  }\n}\n\n% Redefine the quote
environment using the custom style\n\\renewenvironment{quote}\n{%\n
 \\begin{tcolorbox}[myquote]\n}\n{%\n  \\end{tcolorbox}\n}\n\n\n%
\\titlespacing{command}{left spacing}{before spacing}{after
spacing}[right]\n\\titlespacing*{\\section}{1.5ex}{12pt}{0pt}\n\\titlespacing*{\\subsection}{0pt}{0pt}{-6pt}\n\\titlespacing*{\\subsubsection}{0pt}{0pt}{-12pt}\n\n\\titleformat*{\\section}{\\sffamily\\bfseries\\fontsize{30}{20}\\raggedright\\sffamily\\color{libertyblue}}\n\\titleformat*{\\subsection}{\\sffamily\\fontsize{18}{16}\\selectfont\\raggedright\\color{libertyblue}}\n\n\\titleformat*{\\subsubsection}{\\sffamily\\bfseries\\fontsize{15}{16}\\raggedright\\sffamily\\color{libertyblue}}\n\\titleformat*{\\paragraph}{\\sffamily\\fontsize{13}{12}\\raggedright\\bfseries\\color{libertyblue}}\n\\titleformat*{\\subparagraph}{\\sffamily\\fontsize{14}{14}\\raggedright\\bfseries\\ttfamily\\color{libertyblue}}\n\n\n\n\\titleformat{\\paragraph}[block]{\\normalfont\\sffamily\\fontsize{13}{12}\\bfseries\\color{black}}{}{0em}{}\n\\titlespacing*{\\paragraph}{0pt}{0pt}{-6pt}\n\n\n\n\\titleformat{\\subparagraph}{\\normalfont\\sffamily\\fontsize{13}{12}\\bfseries\\color{black}}{}{0em}{}\n\\titlespacing*{\\subparagraph}{0pt}{0pt}{-6pt}\n\n\n\\usepackage[breaklinks=true,linktocpage,xetex]{hyperref}\n\\hypersetup{colorlinks,
citecolor=libertyblue,filecolor=libertyblue,linkcolor=libertyblue,urlcolor=libertyblue}\n\n\\renewcommand\\maketitle{}\n\n\n
     [NO-DEFAULT-PACKAGES]\n      [NO-PACKAGES]"
                      ("\\section{%s}" .
                       "\\section*{%s}")
                      ("\\subsection{%s}" .
                       "\\subsection*{%s}")
                      ("\\subsubsection{%s}" .
                       "\\subsubsection*{%s}")
                      ("\\paragraph{%s}" .
                       "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" .
                       "\\subparagraph*{%s}")
                      )
                     ("my-letter"
                      "\\documentclass[%\n DIV=14,\n fontsize=12pt,\n
parskip=half,\n subject=titled,\n backaddress=false,\n fromalign=left,\n
fromemail=true,\n fromphone=true]{scrlttr2}\n [DEFAULT-PACKAGES]\n
[PACKAGES]\n [EXTRA]")
                     ("article"
                      "\\documentclass[11pt]{article}"
                      ("\\section{%s}" .
                       "\\section*{%s}")
                      ("\\subsection{%s}" .
                       "\\subsection*{%s}")
                      ("\\subsubsection{%s}" .
                       "\\subsubsection*{%s}")
                      ("\\paragraph{%s}" .
                       "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" .
                       "\\subparagraph*{%s}")
                      )
                     ("report"
                      "\\documentclass[11pt]{report}"
                      ("\\part{%s}" .
                       "\\part*{%s}")
                      ("\\chapter{%s}" .
                       "\\chapter*{%s}")
                      ("\\section{%s}" .
                       "\\section*{%s}")
                      ("\\subsection{%s}" .
                       "\\subsection*{%s}")
                      ("\\subsubsection{%s}" .
                       "\\subsubsection*{%s}")
                      )
                     ("book"
                      "\\documentclass[11pt]{book}"
                      ("\\part{%s}" .
                       "\\part*{%s}")
                      ("\\chapter{%s}" .
                       "\\chapter*{%s}")
                      ("\\section{%s}" .
                       "\\section*{%s}")
                      ("\\subsection{%s}" .
                       "\\subsection*{%s}")
                      ("\\subsubsection{%s}" .
                       "\\subsubsection*{%s}")
                      )
                     )
 org-sort-function 'string-collate-lessp
 org-n-level-faces 9
 org-twbs-head-include-scripts nil
 org-highlight-latex-and-related '(latex)
 org-use-speed-commands t
 org-timeline-source-url "/Users/jay/Dropbox/github/
incandescentman.github.io/timeline/dist"
 org-protocol-protocol-alist '(("org-roam-node"
                                :protocol
                                "roam-node"
                                :function
                                org-roam-protocol-open-node)
                               ("org-roam-ref"
                                :protocol
                                "roam-ref"
                                :function
                                org-roam-protocol-open-ref)
                               ("org-roam-node"
                                :protocol
                                "roam-node"
                                :function
                                org-roam-protocol-open-node)
                               ("org-roam-ref"
                                :protocol
                                "roam-ref"
                                :function
                                org-roam-protocol-open-ref)
                               )
 org-roam-capture-preface-hook '(org-roam-dailies--override-capture-time-h
org-roam-capture--try-capture-to-ref-h)
 org-extend-today-until 8
 org-html-checkbox-type 'unicode
 org-list-demote-modify-bullet '(("+" . "-")
                                 ("-" . "+"))
 org-link-translation-function 'toc-org-unhrefify
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-capture-prepare-finalize-hook '(org-roam-capture--install-finalize-h)
 org-src-preserve-indentation t
 org-roam-preview-function 'org-roam-preview-default-function
 org-src-mode-hook '(org-src-babel-configure-edit-buffer
org-src-mode-configure-edit-buffer)
 org-roam-db-autosync-mode t
 org-checkbox-statistics-hook '(ndk/checkbox-list-complete)
 org-confirm-elisp-link-function 'yes-or-no-p
 org-cycle-separator-lines 0
 org-twbs-head-include-default-style nil
 org-superstar-headline-bullets-list '(42 42 42
                                       42)
 org-log-buffer-setup-hook '(org-roam-log--setup
                             spacemacs//org-note-mode)
 org-clock-report-include-clocking-task t
 org-safe-remote-resources '("\\`https://fniessen
\\.github\\.io/org-html-themes/org/theme-bigblow\\.setup\\'")
 org-insert-mode-line-in-empty-file t
 org-hide-leading-stars t
 org-twbs-format-headline-function 'ignore
 org-clock-idle-time 30
 org-todo-keywords '((sequence "TODO" "STARTED"
                      "|" "DONE")
                     (sequence "MISSED" "|"
                      "DONE")
                     (sequence "MISSED ❌" "|"
                      "DONE")
                     (sequence "STARTED" "|"
                      "DONE ✅")
                     (sequence "STARTED 🏁" "|"
                      "DONE ✅")
                     (sequence "Example:" "|")
                     (sequence "NEED TO INVOICE"
                      "INVOICED" "|" "PAID")
                     (sequence "|" "CANCELED")
                     (sequence "Original:" "|"
                      "Revised:")
                     (sequence "REWARD" "|"
                      "REWARDED")
                     (sequence "TO PROCESS" "|"
                      "PROCESSED")
                     )
 org-twbs-postamble-format nil
 org--warnings '("org-element--cache: Org parser error in 2024-10-24.org::297.
Resetting.\n The error was: (error \"Invalid search bound (wrong side of
point)\")\n Backtrace:\n\"  backtrace-to-string(nil)\n  (progn
(backtrace-to-string (backtrace-get-frames 'backtrace)))\n  (if (and
(fboundp 'backtrace-get-frames) (fboundp 'backtrace-to-string)) (progn
(backtrace-to-string (backtrace-get-frames 'backtrace))))\n  (format
\\\"Org parser error in %s::%S. Resetting.\\\\n The error ...\\\"
(buffer-name (current-buffer)) epom err (if (and (fboundp
'backtrace-get-frames) (fboundp 'backtrace-to-string)) (progn
(backtrace-to-string (backtrace-get-frames 'backtrace)))))\n  (let*
((format-string (format \\\"Org parser error in %s::%S. Resetting.\\\\n The
error ...\\\" (buffer-name (current-buffer)) epom err (if (and (fboundp
'backtrace-get-frames) (fboundp 'backtrace-to-string)) (progn
(backtrace-to-string (backtrace-get-frames ...)))))) (format-string (if (or
(not org-element--cache-diagnostics-ring) (not (eq 'backtrace
org-element--cache-self-verify))) format-string (prog1 (concat (format
\\\"Warning(%s): \\\" (buffer-name ...)) format-string
\\\"\\\\nBacktrace:\\\\n  \\\" (mapconcat #'identity (ring-elements
org-element--cache-diagnostics-ring) \\\"\\\\n  \\\")) (setq
org-element--cache-diagnostics-ring nil))))) (if (and (boundp
'org-batch-test) org-batch-test) (error \\\"%s\\\" (concat
\\\"org-element--cache: \\\" format-string)) (setq org--warnings (cons
(concat \\\"org-element--cache: \\\" format-string) org--warnings))
(display-warning '(org-element org-element-cache) (concat
\\\"org-element--cache: \\\" format-string))))\n  (condition-case err
(org-element--parse-to epom) ((debug error) (let* ((format-string (format
\\\"Org parser error in %s::%S. Resetting.\\\\n The error ...\\\"
(buffer-name (current-buffer)) epom err (if (and ... ...) (progn ...))))
(format-string (if (or (not org-element--cache-diagnostics-ring) (not ...))
format-string (prog1 (concat ... format-string \\\"\\\\nBacktrace:\\\\n
 \\\" ...) (setq org-element--cache-diagnostics-ring nil))))) (if (and
(boundp 'org-batch-test) org-batch-test) (error \\\"%s\\\" (concat
\\\"org-element--cache: \\\" format-string)) (setq org--warnings (cons
(concat \\\"org-element--cache: \\\" format-string) org--warnings))
(display-warning '(org-element org-element-cache) (concat
\\\"org-element--cache: \\\" format-string)))) (org-element-cache-reset)
(org-element--parse-to epom)))\n  (if cached-only (if (and
(org-element--cache-active-p) (or (not org-element--cache-sync-requests) (<
epom (aref (car org-element--cache-sync-requests) 1)))) (progn
(org-element--cache-find epom))) (condition-case err (org-element--parse-to
epom) ((debug error) (let* ((format-string (format \\\"Org parser error in
%s::%S. Resetting.\\\\n The error ...\\\" (buffer-name ...) epom err (if
... ...))) (format-string (if (or ... ...) format-string (prog1 ... ...))))
(if (and (boundp 'org-batch-test) org-batch-test) (error \\\"%s\\\" (concat
\\\"org-element--cache: \\\" format-string)) (setq org--warnings (cons
(concat \\\"org-element--cache: \\\" format-string) org--warnings))
(display-warning '(org-element org-element-cache) (concat
\\\"org-element--cache: \\\" format-string)))) (org-element-cache-reset)
(org-element--parse-to epom))))\n  (setq element (if cached-only (if (and
(org-element--cache-active-p) (or (not org-element--cache-sync-requests) (<
epom (aref (car org-element--cache-sync-requests) 1)))) (progn
(org-element--cache-find epom))) (condition-case err (org-element--parse-to
epom) ((debug error) (let* ((format-string (format \\\"Org parser error in
%s::%S. Resetting.\\\\n The error ...\\\" ... epom err ...)) (format-string
(if ... format-string ...))) (if (and (boundp ...) org-batch-test) (error
\\\"%s\\\" (concat \\\"org-element--cache: \\\" format-string)) (setq
org--warnings (cons ... org--warnings)) (display-warning '... (concat
\\\"org-element--cache: \\\" format-string)))) (org-element-cache-reset)
(org-element--parse-to epom)))))\n  (let (element) (if
(org-element--cache-active-p) (progn (if (not (save-current-buffer
(set-buffer (or ... ...)) org-element--cache)) (org-element-cache-reset)
(if cached-only nil (org-element--cache-sync (current-buffer) epom)))))
(setq element (if cached-only (if (and (org-element--cache-active-p) (or
(not org-element--cache-sync-requests) (< epom (aref ... 1)))) (progn
(org-element--cache-find epom))) (condition-case err (org-element--parse-to
epom) ((debug error) (let* ((format-string ...) (format-string ...)) (if
(and ... org-batch-test) (error \\\"%s\\\" ...) (setq org--warnings ...)
(display-warning ... ...))) (org-element-cache-reset)
(org-element--parse-to epom))))) (if (and (org-element--cache-active-p)
element (org-element--cache-verify-element element)) (progn (setq element
(org-element--parse-to epom)))) (if (eq (org-element-type element t)
'org-data) nil (if (and cached-only (not (and element (or (= epom ...) (and
... ... ...) (and ... ... ...) (and ... ... ...))))) nil (if (not (eq
(org-element-type element t) 'section)) element (org-element-at-point (1+
epom) cached-only)))))\n  (save-restriction (widen) (goto-char (or --mepom
(point))) (if (derived-mode-p 'org-mode) nil (display-warning '(org-element
org-element-parser) (format-message \\\"`org-element-at-point' cannot be
used in non-Org b...\\\" (current-buffer) major-mode))) (if (and
cached-only (memq this-command org-element--cache-non-modifying-commands))
(progn (setq cached-only nil))) (let (element) (if
(org-element--cache-active-p) (progn (if (not (save-current-buffer
(set-buffer ...) org-element--cache)) (org-element-cache-reset) (if
cached-only nil (org-element--cache-sync (current-buffer) epom))))) (setq
element (if cached-only (if (and (org-element--cache-active-p) (or (not
org-element--cache-sync-requests) (< epom ...))) (progn
(org-element--cache-find epom))) (condition-case err (org-element--parse-to
epom) ((debug error) (let* (... ...) (if ... ... ... ...))
(org-element-cache-reset) (org-element--parse-to epom))))) (if (and
(org-element--cache-active-p) element (org-element--cache-verify-element
element)) (progn (setq element (org-element--parse-to epom)))) (if (eq
(org-element-type element t) 'org-data) nil (if (and cached-only (not (and
element (or ... ... ... ...)))) nil (if (not (eq (org-element-type element
t) 'section)) element (org-element-at-point (1+ epom) cached-only))))))\n
 (save-excursion (save-restriction (widen) (goto-char (or --mepom (point)))
(if (derived-mode-p 'org-mode) nil (display-warning '(org-element
org-element-parser) (format-message \\\"`org-element-at-point' cannot be
used in non-Org b...\\\" (current-buffer) major-mode))) (if (and
cached-only (memq this-command org-element--cache-non-modifying-commands))
(progn (setq cached-only nil))) (let (element) (if
(org-element--cache-active-p) (progn (if (not (save-current-buffer ...
org-element--cache)) (org-element-cache-reset) (if cached-only nil
(org-element--cache-sync ... epom))))) (setq element (if cached-only (if
(and (org-element--cache-active-p) (or ... ...)) (progn
(org-element--cache-find epom))) (condition-case err (org-element--parse-to
epom) ((debug error) (let* ... ...) (org-element-cache-reset)
(org-element--parse-to epom))))) (if (and (org-element--cache-active-p)
element (org-element--cache-verify-element element)) (progn (setq element
(org-element--parse-to epom)))) (if (eq (org-element-type element t)
'org-data) nil (if (and cached-only (not (and element ...))) nil (if (not
(eq ... ...)) element (org-element-at-point (1+ epom) cached-only)))))))\n
 (save-excursion (cond ((markerp --mepom) (set-buffer (marker-buffer
--mepom))) ((numberp --mepom)) (t (if (let ((idx (or 14 14))) (let*
((parray ...)) (if parray (let* ... ...) (let* ... ...)))) (progn
(set-buffer (let (...) (let* ... ...))))) (setq --mepom (let ((idx (or 0
0))) (let* ((parray ...)) (if parray (let* ... ...) (let* ... ...)))))))
(save-excursion (save-restriction (widen) (goto-char (or --mepom (point)))
(if (derived-mode-p 'org-mode) nil (display-warning '(org-element
org-element-parser) (format-message \\\"`org-element-at-point' cannot be
used in non-Org b...\\\" (current-buffer) major-mode))) (if (and
cached-only (memq this-command org-element--cache-non-modifying-commands))
(progn (setq cached-only nil))) (let (element) (if
(org-element--cache-active-p) (progn (if (not ...)
(org-element-cache-reset) (if cached-only nil ...)))) (setq element (if
cached-only (if (and ... ...) (progn ...)) (condition-case err
(org-element--parse-to epom) (... ... ... ...)))) (if (and
(org-element--cache-active-p) element (org-element--cache-verify-element
element)) (progn (setq element (org-element--parse-to epom)))) (if (eq
(org-element-type element t) 'org-data) nil (if (and cached-only (not ...))
nil (if (not ...) element (org-element-at-point ... cached-only))))))))\n
 (let ((--mepom epom)) (save-excursion (cond ((markerp --mepom) (set-buffer
(marker-buffer --mepom))) ((numberp --mepom)) (t (if (let ((idx ...)) (let*
(...) (if parray ... ...))) (progn (set-buffer (let ... ...)))) (setq
--mepom (let ((idx ...)) (let* (...) (if parray ... ...))))))
(save-excursion (save-restriction (widen) (goto-char (or --mepom (point)))
(if (derived-mode-p 'org-mode) nil (display-warning '(org-element
org-element-parser) (format-message \\\"`org-element-at-point' cannot be
used in non-Org b...\\\" (current-buffer) major-mode))) (if (and
cached-only (memq this-command org-element--cache-non-modifying-commands))
(progn (setq cached-only nil))) (let (element) (if
(org-element--cache-active-p) (progn (if ... ... ...))) (setq element (if
cached-only (if ... ...) (condition-case err ... ...))) (if (and
(org-element--cache-active-p) element (org-element--cache-verify-element
element)) (progn (setq element ...))) (if (eq (org-element-type element t)
'org-data) nil (if (and cached-only ...) nil (if ... element ...))))))))\n
 (if (org-element-type epom t) epom (setq epom (or epom (point))) (let
((--mepom epom)) (save-excursion (cond ((markerp --mepom) (set-buffer
(marker-buffer --mepom))) ((numberp --mepom)) (t (if (let (...) (let* ...
...)) (progn (set-buffer ...))) (setq --mepom (let (...) (let* ... ...)))))
(save-excursion (save-restriction (widen) (goto-char (or --mepom (point)))
(if (derived-mode-p 'org-mode) nil (display-warning '... (format-message
\\\"`org-element-at-point' cannot be used in non-Org b...\\\" ...
major-mode))) (if (and cached-only (memq this-command
org-element--cache-non-modifying-commands)) (progn (setq cached-only nil)))
(let (element) (if (org-element--cache-active-p) (progn ...)) (setq element
(if cached-only ... ...)) (if (and ... element ...) (progn ...)) (if (eq
... ...) nil (if ... nil ...))))))))\n  org-element-at-point()\n
 org-at-item-p()\n  org-indent-add-properties(291 298)\n
 org-indent-refresh-maybe(291 291 3)\n
 run-hook-with-args(org-indent-refresh-maybe 291 291 3)\n
 combine-change-calls-1(291 294 #f(compiled-function () #<bytecode
-0xc34b367726de687>))\n  org-demote-subtree()\n
 smart-org-insert-subheading()\n
 funcall-interactively(smart-org-insert-subheading)\n
 call-interactively(smart-org-insert-subheading nil nil)\n
 command-execute(smart-org-insert-subheading)\n  recursive-edit()\n
 debug(error (error \\\"Invalid search bound (wrong side of point)\\\"))\n
 re-search-forward(\\\"\\\\\\\\[\\\\\\\\([^][]+\\\\\\\\)\\\\\\\\](\\\\\\\\([^)]+\\\\\\\\))\\\"
184013 t)\n  (while (re-search-forward
\\\"\\\\\\\\[\\\\\\\\([^][]+\\\\\\\\)\\\\\\\\](\\\\\\\\([^)]+\\\\\\\\))\\\"
end t) (replace-match \\\"[[\\\\\\\\2][\\\\\\\\1]]\\\" t))\n
 (save-excursion (goto-char beg) (while (re-search-forward
\\\"\\\\\\\\[\\\\\\\\([^][]+\\\\\\\\)\\\\\\\\](\\\\\\\\([^)]+\\\\\\\\))\\\"
end t) (replace-match \\\"[[\\\\\\\\2][\\\\\\\\1]]\\\" t)))\n
 convert-markdown-links-to-org-mode(184020 184013)\n  (let ((beg (point)))
(pasteboard-paste) (replace-smart-quotes beg (point))
(convert-markdown-links-to-org-mode beg (point)))\n
 pasteboard-paste-without-smart-quotes()\n  (if (or (member prev-char
char-set) (member next-char char-set)) (pasteboard-paste-no-spaces)
(pasteboard-paste-without-smart-quotes))\n  (let* ((prev-char
(char-before)) (next-char (char-after)) (char-set '(58 39 40 41 124 91 93
47 92 34 61 60 62 123 125))) (if (or (member prev-char char-set) (member
next-char char-set)) (pasteboard-paste-no-spaces)
(pasteboard-paste-without-smart-quotes)))\n
 pasteboard-paste-spaces-maybe()\n
 funcall-interactively(pasteboard-paste-spaces-maybe)\n
 call-interactively(pasteboard-paste-spaces-maybe nil nil)\n
 command-execute(pasteboard-paste-spaces-maybe)\n\"\n Please report this to
Org mode mailing list (M-x org-submit-bug-report).")
 org-latex-logfiles-extensions '("lof" "lot"
                                 "tex" "odt"
                                 "aux" "idx"
                                 "log" "out"
                                 "toc" "nav"
                                 "snm" "vrb"
                                 "dvi"
                                 "fdb_latexmk"
                                 "blg" "brf"
                                 "fls" "entoc"
                                 "ps" "spl" "bbl")
 org-roam-capture-new-node-hook '(org-roam-capture--insert-captured-ref-h)
 org-export-with-timestamps 'active
 org-support-shift-select 'always
 org-structure-template-alist '(("a" .
                                 "export ascii")
                                ("c" . "center")
                                ("C" . "comment")
                                ("e" . "example")
                                ("x" . "example")
                                ("le" . "example")
                                ("E" . "export")
                                ("h" .
                                 "export html")
                                ("l" .
                                 "src emacs-lisp")
                                ("el" .
                                 "src emacs-lisp")
                                ("la" .
                                 "export latex")
                                ("q" . "quote")
                                ("s" . "src")
                                ("sh" . "src sh")
                                ("f" .
                                 "example fountain")
                                ("v" .
                                 "example verse")
                                )
 org-blocker-hook '(org-block-todo-from-checkboxes
org-block-todo-from-children-or-siblings-or-parent)
 org-html-text-markup-alist '((bold .
                               "<strong>%s</strong>")
                              (code .
                               "<code>%s</code>")
                              (italic .
                               "<em>%s</em>")
                              (strike-through .
                               "<del>%s</del>")
                              (underline .
                               "<span class=\"underline\">%s</span>")
                              (verbatim .
                               "<code>%s</code>")
                              )
 org-export-timestamp-file nil
 org-speed-command-hook '(org-speed-command-activate
org-babel-speed-command-activate)
 org-html-format-inlinetask-function
'org-html-format-inlinetask-default-function
 org-clock-persist-file "~/.emacs.d/.cache/org-clock-save.el"
 org-ascii-format-inlinetask-function 'org-ascii-format-inlinetask-default
 org-latex-default-class "elegant"
 org-latex-prefer-user-labels t
 org-html-metadata-timestamp-format "%m-%d %a %H:%M"
 org-export-backends '(ascii html icalendar latex
                       md)
 org-enforce-todo-dependencies t
 org-fold-core-isearch-open-function 'org-fold-core--isearch-reveal
 org-export-with-smart-quotes t
 org-clock-in-resume t
 org-pomodoro-finished-hook '((lambda nil
                               (do-applescript
                                (format
                                 "\nignoring application responses\n tell
application \"System Events\"\nkeystroke \"B\" using {command down, shift
down, option down, control down} -- start Pomodoro One\nkey code {118}\nend
tell\nend ignoring\n\n\nset now to current date\nset nowTime to (hours of
now) & \":\" & (minutes of now)\nset pomodoroStart to (current date) - 25 *
minutes\nset pStartTime to (hours of pomodoroStart) & \":\" & (minutes of
pomodoroStart)\nset achieved to text returned of (display dialog \"What did
you achieve in this Pomodoro?\" default answer \"\")\nset entry_text to \"#
Bookwriting:\" & pStartTime & \" - \" & time string of now & \"\n\n\" &
achieved & \"\n\n#pomodoro \"\n\n")
                                )
                               )
                              )
 org-preview-latex-default-process 'verbatim
 org-M-RET-may-split-line '((item . t))
 org-clock-persist t
 org-latex-format-inlinetask-function
'org-latex-format-inlinetask-default-function
 org-persist-before-write-hook '(org-element--cache-persist-before-write)
 org-emphasis-alist '(("*" bold) ("/" italic)
                      ("_" underline)
                      ("~" org-code verbatim)
                      ("=" flyspell-incorrect)
                      ("+" (:strike-through t)))
 org-tab-first-hook '(yas-org-very-safe-expand
                      org-babel-hide-result-toggle-maybe
org-babel-header-arg-expand)
 org-export-with-toc nil
 org-link-shell-confirm-function 'yes-or-no-p
 org-babel-pre-tangle-hook '(save-buffer)
 org-superstar-remove-leading-stars t
 org-roam-completion-everywhere t
 org-agenda-loop-over-headlines-in-active-region nil
 org-fontify-quote-and-verse-blocks t
 org-attach-id-dir "/Users/jay/Dropbox/roam/attachments"
 org-clock-auto-clock-resolution t
 org-todo-keyword-faces '(("PROCESSED"
                           :foreground
                           "LavenderBlush"
                           :background "darkgrey"
                           :weight bold)
                          ("NEXT" :background
                           "medium sea green"
                           :foreground "white"
                           :weight bold)
                          ("ACTION" :foreground
                           "medium sea green"
                           :weight bold)
                          ("WAITING" :background
                           "yellow" :foreground
                           "purple" :weight bold)
                          ("EVENT" :background
                           "gray25" :foreground
                           "white" :weight bold)
                          ("PROJECT" :background
                           "firebrick"
                           :foreground "white"
                           :weight bold)
                          ("STARTED" :background
                           "dodger blue"
                           :foreground "white"
                           :weight bold)
                          ("DONE" :background
                           "white" :foreground
                           "black" :weight bold)
                          )
 org-export-format-drawer-function 'jbd-org-export-format-drawer
 org-capture-mode-hook '(spacemacs//org-capture-start)
 org-html-prefer-user-labels t
 org-roam-mode-sections '(org-roam-backlinks-section
org-roam-reflinks-section org-roam-unlinked-references-section)
 org-occur-hook '(org-first-headline-recenter)
 org-roam-log-setup-hook '(org-roam--register-completion-functions-h)
 org-latex-image-default-width "370pt"
 org-html-head-include-default-style nil
 org-export-with-drawers t
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-html-html5-fancy t
 org-treat-S-cursor-todo-selection-as-state-change nil
 org-roam-node-annotation-function 'org-roam-node-read--annotation
 org-link-parameters '(("imghttps"
                        :image-data-fun
                        org-image-link)
                       ("imghttp" :image-data-fun
                        org-image-link)
                       ("message" :follow
                        org-mac-link-mail-open)
                       ("x-devonthink-item"
                        :follow
                        org-mac-link-devonthink-item-open)
                       ("mac-evernote" :follow
                        org-mac-link-evernote-note-open)
                       ("mac-outlook" :follow
                        org-mac-link-outlook-message-open)
                       ("acrobat" :follow
                        org-mac-link-acrobat-open)
                       ("skim" :follow
                        org-mac-link-skim-open)
                       ("addressbook" :follow
                        org-mac-link-addressbook-item-open)
                       ("x-together-item" :follow
                        org-mac-link-together-item-open)
                       ("eww" :follow
                        org-eww-open :store
                        org-eww-store-link)
                       ("rmail" :follow
                        org-rmail-open :store
                        org-rmail-store-link)
                       ("mhe" :follow
                        org-mhe-open :store
                        org-mhe-store-link)
                       ("irc" :follow
                        org-irc-visit :store
                        org-irc-store-link
                        :export org-irc-export)
                       ("info" :follow
                        org-info-open :export
                        org-info-export :store
                        org-info-store-link
                        :insert-description
                        org-info-description-as-command)
                       ("gnus" :follow
                        org-gnus-open :store
                        org-gnus-store-link)
                       ("docview" :follow
                        org-docview-open :export
                        org-docview-export :store
                        org-docview-store-link)
                       ("bibtex" :follow
                        org-bibtex-open :store
                        org-bibtex-store-link)
                       ("bbdb" :follow
                        org-bbdb-open :export
                        org-bbdb-export :complete
                        org-bbdb-complete-link
                        :store
                        org-bbdb-store-link)
                       ("w3m" :store
                        org-w3m-store-link)
                       ("doi" :follow
                        org-link-doi-open :export
                        org-link-doi-export)
                       ("roam" :follow
                        org-roam-link-follow-link)
                       ("yt" :follow
                        org-yt-follow :export
                        org-yt-export
                        :image-data-fun
                        org-yt-image-data-fun)
                       ("attachment" :follow
                        org-attach-follow
                        :complete
                        org-attach-complete-link)
                       ("id" :follow
                        org-roam-id-open :store
                        org-id-store-link-maybe)
                       ("hook" :follow my/hook
                        :export nil)
                       ("file+sys")
                       ("file+emacs")
                       ("shell" :follow
                        org-link--open-shell)
                       ("news" :follow
                        #[514
                          "\301\300\302 Q \"\207"
                          ["news" browse-url ":"]
                          6 "\n\n(fn URL ARG)"]
                        )
                       ("mailto" :follow
                        #[514
                          "\301\300\302 Q \"\207"
                          ["mailto" browse-url
                           ":"]
                          6 "\n\n(fn URL ARG)"]
                        )
                       ("https" :follow
                        #[514
                          "\301\300\302 Q \"\207"
                          ["https" browse-url ":"]
                          6 "\n\n(fn URL ARG)"]
                        )
                       ("http" :follow
                        #[514
                          "\301\300\302 Q \"\207"
                          ["http" browse-url ":"]
                          6 "\n\n(fn URL ARG)"]
                        )
                       ("ftp" :follow
                        #[514
                          "\301\300\302 Q \"\207"
                          ["ftp" browse-url ":"]
                          6 "\n\n(fn URL ARG)"]
                        )
                       ("help" :follow
                        org-link--open-help
                        :store
                        org-link--store-help)
                       ("file" :complete
                        org-link-complete-file)
                       ("elisp" :follow
                        org-link--open-elisp)
                       )
 org-html-format-headline-function
'org-html-format-headline-default-function
 org-roam-capture-templates '(("A"
                               "accountability and task capture"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head

"accountability/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE:
${title}\n#+FILETAGS: :accountability:")
                               :unnarrowed t)
                              ("a"
                               "article notes or books and articles"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head

"literature-notes/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE:
${title}\n#+FILETAGS: :literaturenote:")
                               :unnarrowed t)
                              ("b"
                               "original writing"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "writing/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :writing:")
                               :unnarrowed t)
                              ("B" "Plans" plain
                               "%?" :target
                               (file+head
                                "project/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :project:\n- Links ::\n- Source ::\n\n\n*
${title}\n")
                               :unnarrowed t)
                              ("C"
                               "creative idea"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "ideas/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :idea:")
                               :unnarrowed t)
                              ("c" "Conversation"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "conversations/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :conversation:")
                               :unnarrowed t)
                              ("d"
                               "documents and deliverables"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "documents/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :document:")
                               :unnarrowed t)
                              ("e" "emacs" plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "emacs/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :emacs:")
                               :unnarrowed t)
                              ("f"
                               "finances and housekeeping"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "finances/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :finances:")
                               :unnarrowed t)
                              ("g"
                               "groups and organizations"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "groups/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :groups:")
                               :unnarrowed t)
                              ("I" "intelligence"
                               plain
                               "- Links ::\n- Source ::\n\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "AI/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE:
${title}\n#+FILETAGS: :intelligence:")
                               :unnarrowed t)
                              ("k" "kanban" plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "kanban/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :kanban:")
                               :unnarrowed t)
                              ("l"
                               "logistics of OpenAI"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "logistics/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :library:")
                               :unnarrowed t)
                              ("L"
                               "Learning, lectures, and classes"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "lectures/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :learning:")
                               :unnarrowed t)
                              ("n" "note" plain
                               "- Links ::\n- Source ::\n\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "notes/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :note:")
                               :unnarrowed t)
                              ("o"
                               "OpenAI, i.e. work"
                               plain
                               "- Links ::\n- Source ::\n\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "notes/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :work:")
                               :unnarrowed t)
                              ("O"
                               "Outline / Structure / Schelling Points"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "structure/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :structure:")
                               :unnarrowed t)
                              ("p" "person" plain
                               "%?" :target
                               (file+head
                                "person/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :person:\n- Links ::
[[id:20240426T130414.177117][🌐 People]]\n- Source ::\n\n\n* ${title}\n")
                               :unnarrowed t)
                              ("q"
                               "quotes about AI"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "quotes/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :quote:")
                               :unnarrowed t)
                              ("S"
                               "Storytelling and Writing"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "storytelling/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :storytelling:")
                               :unnarrowed t)
                              ("T" "Travel" plain
                               "%?" :target
                               (file+head
                                "travel/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :travel:\n- Links ::\n- Source ::\n\n\n*
${title}\n")
                               :unnarrowed t)
                              ("W" "writers"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "writers/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :writers:person:")
                               :unnarrowed t)
                              ("w"
                               "lectures and public talks"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "lectures/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :lectures:")
                               :unnarrowed t)
                              ("X" "exemplars"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "exemplars/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :exemplars:")
                               :unnarrowed t)
                              ("x" "cuts" plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "cuts/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :cuts:")
                               :unnarrowed t)
                              ("z" "zork" plain
                               "- Links ::\nSource ::\n\n\n* ${title}\n%?"
                               :target
                               (file+head


        (lambda





                   nil





                   (concat

















                               (read-string "Enter file path: ")

















                               "/%<%Y%m%d%H%M%S>-${slug}.org")





                   )


        "#+TITLE: ${title}\n#+FILETAGS: :work:")
                               :unnarrowed t)
                              ("$" "consumer"
                               plain
                               "- Links ::\n- Source ::\n\n* ${title}\n%?"
                               :target
                               (file+head
                                "consumer/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :memoir:")
                               :unnarrowed t)
                              )
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-attach-auto-tag "ATTACHMENTS"
 org-refile-allow-creating-parent-nodes 'confirm
 org-agenda-restore-windows-after-quit t
 org-export-date-timestamp-format "%Y%m%d %I:%M%p"
 org-twbs-postamble nil
 org-use-fast-todo-selection t
 org-latex-text-markup-alist '((bold .
                                "\\textbf{%s}")
                               (code . verb)
                               (italic .
                                "\\textit{%s}")
                               (strike-through .
                                "\\sout{%s}")
                               (underline .
                                "\\uline{%s}")
                               )
 org-priority-start-cycle-with-default nil
 org-latex-inline-image-rules '(("file" .

 "\\.\\(pdf\\|jpeg\\|jpg\\|png\\|ps\\|eps\\|tikz\\|pgf\\|svg\\|gif\\)\\'")
                                )
 org-blank-before-new-entry '((heading . always)
                              (plain-list-item))
 org-indent-mode-turns-off-org-adapt-indentation nil
 org-imenu-depth 8
 org-footnote-define-inline t
 org-html-footnotes-section "<div id=\"footnotes\">\n<h2
class=\"footnotes\">%s </h2>\n<div id=\"footnote\">\n%s\n</div>\n</div>"
 org-clock-persist-query-resume nil
 org-timestamp-custom-formats '("<%a %m/%e/%Y>" .
                                "<%a %B %e %l:%M %p>")
 org-latex-pdf-process '("xelatex -shell-escape -interaction nonstopmode
-output-directory %o %f" "xelatex -shell-escape -interaction nonstopmode
-output-directory %o %f" "xelatex -shell-escape -interaction nonstopmode
-output-directory %o %f")
 org-return-follows-link t
 org-transclusion-extensions '(org-transclusion-src-lines
org-transclusion-font-lock org-transclusion-indent-mode)
 org-outline-path-complete-in-steps nil
 org-special-ctrl-a/e t
 org-tags-column 40
 org-id-method 'ts
 org-tab-before-tab-emulation-hook '(org-tempo-complete-tag)
 org-superstar-item-bullet-alist '((42 . 183)
                                   (43 . 183)
                                   (45 . 183))
 org-roam-indirect-buffer-hook '(org-roam--register-completion-functions-h)
 org-clock-into-drawer nil
 org-list-indent-offset 1
 org-list-allow-alphabetical t
 org-twbs-link-home "http://jaydixit.com"
 org-ascii-table-use-ascii-art t
 )

[-- Attachment #2: Type: text/html, Size: 131119 bytes --]

^ permalink raw reply	[relevance 10%]

* Re: figures not exported properly by ox-latex
  2024-07-09 20:15  0% ` Karthik Chikmagalur
@ 2024-07-11  8:39  0%   ` mahmood sheikh
  0 siblings, 0 replies; 200+ results
From: mahmood sheikh @ 2024-07-11  8:39 UTC (permalink / raw)
  To: Karthik Chikmagalur; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1277 bytes --]

it might've been fixed for figures as its been a while, but shouldnt latex
environments with #+caption: and #+name: above them be exported as figures?
because currently the user has to write \begin{figure} and \end{figure}
explicitly which would work but may not be as practical for other ox
backends like html i think? perhaps im wrong.

On Tue, Jul 9, 2024 at 11:15 PM Karthik Chikmagalur <
karthikchikmagalur@gmail.com> wrote:

> > im on tecosaur's dev branch (version 9.7-pre)
> > i have the following in an org file:
> > ```org
> > #+name: fig-switching-circuit-1
> > #+caption: implementation of \(p\)
> > [[attachment:circuit.svg]]
> > ```
> > it gets turned into this
> > ```
> >
> \includesvg[width=.9\linewidth]{/home/mahmooz/brain/notes/data/9e/5ba2ce-c383-4396-a2cb-891465f14d51/circuit}\\[0pt]
> > ```
>
> Cannot reproduce.  I get the following:
>
> \begin{figure}[htbp]
> \centering
> \includesvg[width=.9\linewidth]{/tmp/circuit}
> \caption{\label{fig-switching-circuit-1}implementation of \(p\)}
> \end{figure}
>
> Perhaps you have customized the LaTeX export process in some way?  Also
> note that we don't touch any of the LaTeX generation code in ox-latex
> except the parts handling LaTeX preview images.
>
> Karthik
>

[-- Attachment #2: Type: text/html, Size: 1651 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: figures not exported properly by ox-latex
  2024-02-02 11:39  8% figures not exported properly by ox-latex mahmood sheikh
@ 2024-07-09 20:15  0% ` Karthik Chikmagalur
  2024-07-11  8:39  0%   ` mahmood sheikh
  0 siblings, 1 reply; 200+ results
From: Karthik Chikmagalur @ 2024-07-09 20:15 UTC (permalink / raw)
  To: mahmood sheikh, emacs-orgmode

> im on tecosaur's dev branch (version 9.7-pre)
> i have the following in an org file:
> ```org
> #+name: fig-switching-circuit-1
> #+caption: implementation of \(p\)
> [[attachment:circuit.svg]]
> ```
> it gets turned into this
> ```
> \includesvg[width=.9\linewidth]{/home/mahmooz/brain/notes/data/9e/5ba2ce-c383-4396-a2cb-891465f14d51/circuit}\\[0pt]
> ```

Cannot reproduce.  I get the following:

\begin{figure}[htbp]
\centering
\includesvg[width=.9\linewidth]{/tmp/circuit}
\caption{\label{fig-switching-circuit-1}implementation of \(p\)}
\end{figure}

Perhaps you have customized the LaTeX export process in some way?  Also
note that we don't touch any of the LaTeX generation code in ox-latex
except the parts handling LaTeX preview images.

Karthik


^ permalink raw reply	[relevance 0%]

* Re: SMART goals and bolding the first letter
  @ 2024-05-27 16:21  8% ` Dr. Arne Babenhauserheide
  0 siblings, 0 replies; 200+ results
From: Dr. Arne Babenhauserheide @ 2024-05-27 16:21 UTC (permalink / raw)
  To: Sharon Kimble; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 871 bytes --]

Sharon Kimble <boudiccas@skimble09.plus.com> writes:

> How can I bold the first letter of a word please? I'm trying to do this -
>   
> ````
> - - *S*pecific -  You don’t want a vague goal. 
> ````
>
> Its part of a section explaining SMART goals.
>
> Any ideas please?    

I don’t know a pure org method, but if this is for LaTeX, you can use:

    @@latex:\textbf{@@S@@latex:}\nobreak\hspace{0pt}@@pecific.

(for the cleaner looking method: https://tex.stackexchange.com/a/267806 )

If this is HTML, you can CSS it:

#+html: <style>.first-letter-bold li::first-letter {font-weight: bold}</style>

#+attr_html: :class first-letter-bold
- Specific
- Measurable
- ...

See https://developer.mozilla.org/en-US/docs/Web/CSS/::first-letter

Best wishes,
Arne
-- 
Unpolitisch sein
heißt politisch sein,
ohne es zu merken.
draketo.de

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 1125 bytes --]

^ permalink raw reply	[relevance 8%]

* Re: [PATCH] lisp/org.el: Obsolete `org-cached-entry-get' in favor of `org-entry-get'
  @ 2024-05-01 17:14  7%       ` Morgan Smith
  0 siblings, 0 replies; 200+ results
From: Morgan Smith @ 2024-05-01 17:14 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1063 bytes --]

Ihor Radchenko <yantar92@posteo.net> writes:
>
> However, please move the obsolete function definition to org-compat
> instead of removing it completely. We do it to avoid unexpected breakage
> for people and libraries who happen to use this public function.

Done.  See attached

> Also, with the old approach, if you observe slowdowns, you likely have
> some property being calculated slowly (like BLOCKED in my case). Do you
> happen to know which property is it for your setup?

According to my profiler, I think it's using 30% of the CPU time during
my custom org-clock-sum just to get ITEM.  I suppose it's because it
thinks it has to grab and cache everything when all I'm after is ITEM.
I don't see anything else that looks suspicious in the profiler so I
suspect you're seeing a much worse case then I am.  I'll copy paste my
previous performance numbers here again just so you can see my slowdown
is only between 1.5x and 3x.


org-cached-entry-get
1st run: 26.868990287
2nd run: 16.043983143

org-entry-get
1st run: 18.209056578
2nd run: 5.003186764



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Obsolete-org-cached-entry-get-in-favor-of-org-entry-.patch --]
[-- Type: text/x-patch, Size: 3679 bytes --]

From 5d9cef1250ef1eb656b84d3168ebfecb0e9c9c5c Mon Sep 17 00:00:00 2001
From: Morgan Smith <Morgan.J.Smith@outlook.com>
Date: Wed, 1 May 2024 12:36:40 -0400
Subject: [PATCH] Obsolete `org-cached-entry-get' in favor of `org-entry-get'

We have a better performing cache mechanism in `org-entry-get'.

* lisp/org.el (org-make-tags-matcher): Replace uses of
`org-cached-entry-get' with `org-entry-get'.
(org-cached-entry-get): Move to ...
* lisp/org-compat.el (org-cached-entry-get): ... here.  Obsolete in
favor of `org-entry-get'.
---
 lisp/org-compat.el | 20 ++++++++++++++++++++
 lisp/org.el        | 20 ++------------------
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index 11eb905ee..b73cfc910 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -649,6 +649,26 @@ Counting starts at 1."
 (define-obsolete-variable-alias 'org-plantuml-executable-args 'org-plantuml-args
   "Org 9.6")
 
+(defvar org-cached-props nil)
+(defun org-cached-entry-get (pom property)
+  (if (or (eq t org-use-property-inheritance)
+	  (and (stringp org-use-property-inheritance)
+	       (let ((case-fold-search t))
+		 (string-match-p org-use-property-inheritance property)))
+	  (and (listp org-use-property-inheritance)
+	       (member-ignore-case property org-use-property-inheritance)))
+      ;; Caching is not possible, check it directly.
+      (org-entry-get pom property 'inherit)
+    ;; Get all properties, so we can do complicated checks easily.
+    (cdr (assoc-string property
+		       (or org-cached-props
+			   (setq org-cached-props (org-entry-properties pom)))
+		       t))))
+
+(make-obsolete 'org-cached-entry-get
+               "Performs badly.  Instead use `org-entry-get' with the argument INHERIT set to `selective'"
+               "9.7")
+
 (defconst org-latex-line-break-safe "\\\\[0pt]"
   "Linebreak protecting the following [...].
 
diff --git a/lisp/org.el b/lisp/org.el
index 2d1a2055f..36b52b0ab 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -11480,22 +11480,6 @@ are also TODO tasks."
 
 (defalias 'org-tags-sparse-tree 'org-match-sparse-tree)
 
-(defvar org-cached-props nil)
-(defun org-cached-entry-get (pom property)
-  (if (or (eq t org-use-property-inheritance)
-	  (and (stringp org-use-property-inheritance)
-	       (let ((case-fold-search t))
-		 (string-match-p org-use-property-inheritance property)))
-	  (and (listp org-use-property-inheritance)
-	       (member-ignore-case property org-use-property-inheritance)))
-      ;; Caching is not possible, check it directly.
-      (org-entry-get pom property 'inherit)
-    ;; Get all properties, so we can do complicated checks easily.
-    (cdr (assoc-string property
-		       (or org-cached-props
-			   (setq org-cached-props (org-entry-properties pom)))
-		       t))))
-
 (defun org-global-tags-completion-table (&optional files)
   "Return the list of all tags in all agenda buffer/files.
 Optional FILES argument is a list of files which can be used
@@ -11670,7 +11654,7 @@ See also `org-scan-tags'."
 				   ("CATEGORY"
 				    '(org-get-category (point)))
 				   ("TODO" 'todo)
-				   (p `(org-cached-entry-get nil ,p))))
+				   (p `(org-entry-get (point) ,p 'selective))))
 			     ;; Determine operand (aka. property
 			     ;; value).
 			     (pv (match-string 8 term))
@@ -11707,7 +11691,7 @@ See also `org-scan-tags'."
 	      (setq term rest)))
 	  (push `(and ,@tagsmatcher) orlist)
 	  (setq tagsmatcher nil))
-	(setq tagsmatcher `(progn (setq org-cached-props nil) (or ,@orlist)))))
+	(setq tagsmatcher `(or ,@orlist))))
 
     ;; Make the TODO matcher.
     (when (org-string-nw-p todomatch)
-- 
2.41.0


^ permalink raw reply related	[relevance 7%]

* Re: [Pre-PATCH] Overhaul of the LaTeX preview system
  @ 2024-04-18 20:13  9%   ` Yaroslav Drachov
  0 siblings, 0 replies; 200+ results
From: Yaroslav Drachov @ 2024-04-18 20:13 UTC (permalink / raw)
  To: Karthik Chikmagalur; +Cc: orgmode, emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 6122 bytes --]

My system-configuration-features are

"ACL GIF GLIB GMP GNUTLS JPEG JSON LCMS2 LIBXML2 MODULES NOTIFY KQUEUE NS PDUMPER PNG RSVG SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER WEBP XIM XWIDGETS ZLIB".

RSVG is in the list.

org-latex-preview-check-health diagnostic info:

(:image-converters (("convert" "Version: ImageMagick 7.1.1-29 Q16-HDRI x86_64 21991 https://imagemagick.org" "/usr/local/bin/convert") ("dvisvgm" "dvisvgm 3.2.2" "/Library/TeX/Distributions/Programs/texbin/dvisvgm") ("dvipng" "This is dvipng 1.17 Copyright 2002-2015, 2019 Jan-Ake Larsson" "/Library/TeX/Distributions/Programs/texbin/dvipng")) :latex-processors (("lualatex" "This is LuaHBTeX, Version 1.18.0 (TeX Live 2024)" "/Library/TeX/Distributions/Programs/texbin/lualatex") ("xelatex" "XeTeX 3.141592653-2.6-0.999996 (TeX Live 2024)" "/Library/TeX/Distributions/Programs/texbin/xelatex") ("pdflatex" "pdfTeX 3.141592653-2.6-1.40.26 (TeX Live 2024)" "/Library/TeX/Distributions/Programs/texbin/pdflatex")) :interactive t :org-version "9.7-pre" :modified ((org-latex-preview-appearance-options :foreground auto :background "Transparent" :scale 1.6 :zoom 1.2 :page-width 0.8 :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")) (org-persist-after-read-hook org-element--cache-persist-after-read) (org-latex-engraved-theme . modus-operandi) (org-latex-minted-langs (jupyter-Wolfram\ Language "Wolfram Language") (jupyter-python "python") (emacs-lisp "common-lisp") (cc "c++") (cperl "perl") (shell-script "bash") (caml "ocaml")) (org-persist-before-read-hook org-element--cache-persist-before-read) (org-latex-format-drawer-function . #[514 "\207" [] 3 "

(fn _ CONTENTS)"]) (org-latex-format-headline-function . org-latex-format-headline-default-function) (org-latex-preview-live-debounce . 0.25) (org-latex-preview-process-alist (dvipng :programs ("latex" "dvipng") :description "dvi > png" :message "you need to install the programs: latex and dvipng." :image-input-type "dvi" :image-output-type "png" :latex-compiler ("%l -interaction nonstopmode -output-directory %o %f") :latex-precompiler ("%l -output-directory %o -ini -jobname=%b \"&%L\" mylatexformat.ltx %f") :image-converter ("dvipng --follow -D %D -T tight --depth --height -o %B-%%09d.png %f") :transparent-image-converter ("dvipng --follow -D %D -T tight -bg Transparent --depth --height -o %B-%%09d.png %f")) (dvisvgm :programs ("latex" "dvisvgm") :description "dvi > svg" :message "you need to install the programs: latex and dvisvgm." :image-input-type "dvi" :image-output-type "svg" :latex-compiler ("%l -interaction nonstopmode -output-directory %o %f") :latex-precompiler ("%l -output-directory %o -ini -jobname=%b \"&%L\" mylatexformat.ltx %f") :image-converter ("dvisvgm --page=1- --optimize --clipjoin --relative --no-fonts -v3 --message='processing page {?pageno}: output written to {?svgfile}' --bbox=preview -o %B-%%9p.svg %f")) (imagemagick :programs ("pdflatex" "convert") :description "pdf > png" :message "you need to install the programs: latex and imagemagick." :image-input-type "pdf" :image-output-type "png" :latex-compiler ("pdflatex -interaction nonstopmode -output-directory %o %f") :latex-precompiler ("pdftex -output-directory %o -ini -jobname=%b \"&pdflatex\" mylatexformat.ltx %f") :image-converter ("convert -density %D -trim -antialias %f -quality 100 %B-%%09d.png"))) (org-latex-classes ("tikzposter" "\\documentclass[]{tikzposter}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("extarticle" "\\documentclass[14pt]{extarticle}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("article" "\\documentclass[11pt]{article}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) ("report" "\\documentclass[11pt]{report}" ("\\part{%s}" . "\\part*{%s}") ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) ("book" "\\documentclass[11pt]{book}" ("\\part{%s}" . "\\part*{%s}") ("\\chapter{%s}" . "\\chapter*{%s}") ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))) (org-latex-engraved-preamble . "\\usepackage{fvextra}

[FVEXTRA-SETUP]

% Make line numbers smaller and grey.
\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}

\\usepackage{xcolor}

% In case engrave-faces-latex-gen-preamble has not been run.
\\providecolor{EfD}{HTML}{f7f7f7}
\\providecolor{EFD}{HTML}{28292e}

% Define a Code environment to prettily wrap the fontified code.
\\usepackage[breakable,xparse]{tcolorbox}
\\tcbset{nobeforeafter, enlarge top initially by=7pt}
\\DeclareTColorBox[]{Code}{o}%
{colback=EfD!98!EFD, colframe=EfD!95!EFD,
  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
  colupper=EFD,
  IfNoValueTF={#1}%
  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
    boxrule=0.5pt, left=2pt}%
  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
  right=2pt, top=1pt, bottom=0.5pt,
  breakable}

[LISTINGS-SETUP]") (org-latex-src-block-backend . engraved) (org-latex-preview-auto-ignored-commands previous-line next-line) (org-latex-preview-process-default . dvipng) (org-latex-caption-above) (org-latex-format-inlinetask-function . org-latex-format-inlinetask-default-function) (org-persist-before-write-hook org-element--cache-persist-before-write) (org-latex-preview-live . t)))


Best wishes,
Yaroslav

> 18 апр. 2024 г., в 23:04, Karthik Chikmagalur <karthikchikmagalur@gmail.com> написал(а):
> 
> system-configuration-features


[-- Attachment #2: Type: text/html, Size: 7967 bytes --]

^ permalink raw reply	[relevance 9%]

* [BUG]: elusive vertical white-space errors in engraved source block export
@ 2024-02-15  9:18 17% gerard.vermeulen
  0 siblings, 0 replies; 200+ results
From: gerard.vermeulen @ 2024-02-15  9:18 UTC (permalink / raw)
  To: Emacs orgmode, Ihor Radchenko

[-- Attachment #1: Type: text/plain, Size: 845 bytes --]

Hi,

attached you'll find a pdf file showing the elusive vertical white-space 
errors
using the engraved source block export backend that I demonstrated 
yesterday
evening.

I also attached the org demonstration file and the mini-library that 
makes the
demonstration file work.

You can find also everything at https://github.com/gav451/org-exp-exp
(except for the pdf).

I checked that the errors are also present in a minimal "clean" 
environment
where the only installed packages are engrave-faces, auctex, and 
pdf-tools.

I have also seen these kind of errors on Gentoo systems, but I have no 
access
to those anymore.

I have a patch which is unacceptable because it limits the font size to
"normalsize" and it requires visible draw boxes around floating 
listings.
Nevertheless, I attach it to show where I got stuck.

Regards -- Gerard

[-- Attachment #2: any-backend.org --]
[-- Type: application/octet-stream, Size: 26890 bytes --]

#+title: Switch to any Org LaTeX source block export backend
#+author: Gerard Vermeulen
#+latex-class: article
#+latex_class_options: [11pt,a4paper,english,svgnames]
#+property: header-args:emacs-lisp :tangle any-backend.el
#+options: ^:{} date:nil toc:2 timestamp:nil
#+startup: showeverything
#+begin_src latex :noweb yes :results raw
  ,#+latex_header: <<lst:latex-header>>
#+end_src

* Introduction
:PROPERTIES:
:CUSTOM_ID: sec:introduction
:END:

This document demonstrates how to switch between the four different Org LaTeX
export source code block backends ~verbatim~, ~listings~, ~minted~ and
~engraved~.  In order to explore a bug in the ~engraved~ backend, the
sub-backends ~plain-engraved~, ~fixed-engraved~, and ~boxed-engraved~ replace
the ~engraved~ backend in the entry point [[ab-do-it]].

Sub-backend ~plain-engraved~ selects Org upstream, sub-backend ~fixed-engraved~
selects a bug work-around, and sub-backend ~boxed-engraved~ selects a bug
amplification which may lead to terrible ~pdf~ output.

Execution of the entry point listing [[ab-do-it]] assumes tangling of this file to
[[./any-backend.el]] and evaluation of [[./any-backend.el]] or installation of
[[./any-backend.el]] by means of ~package-install-from-buffer~.

* Minimal setup                                                    :noexport:
:PROPERTIES:
:CUSTOM_ID: sec:minimal-setup
:END:

Listing [[lst:insert-init]] uses ~ab-org-babel-file-as-block-body~ to insert the
contents of [[~/org-emacs/init.el][~/org-emacs/init.el]] into listing [[lst:insert-init-result]].

#+caption[Insert minimal dot-emacs]:
#+caption: Insert minimal dot-emacs.
#+header: :wrap "src emacs-lisp -n :eval never :tangle no"
#+name: lst:insert-init
#+header: :var filename="~/org-emacs/init.el"
#+begin_src emacs-lisp -n :eval no-export :exports both :tangle no
  (unless (or (featurep 'any-backend)
              (require 'any-backend nil 'noerror))
    (user-error "Evaluate or install `any-backend.el' (after tangling?)"))
  (ab-org-babel-file-as-block-body filename)
#+end_src

#+caption[Minimal dot-emacs]:
#+caption: Minimal dot-emacs.
#+name: lst:insert-init-result
#+RESULTS: lst:insert-init
#+begin_src emacs-lisp -n :eval never :tangle no
  ;; Almost everybody should edit the next line.
  (push (expand-file-name "~/VCS/org-mode/lisp") load-path)
  ;; Undo calling `org-ctags-enable'.
  (defun org-ctags-disable ()
    "Undo calling `org-ctags-enable'."
    (put 'org-mode 'find-tag-default-function nil)
    (setq org-ctags-enabled-p nil)
    (setq org-open-link-functions nil))
  (with-eval-after-load 'org-ctags
    (org-ctags-disable))
  ;; `tab'-related options affect `engrave-faces'.
  (setopt tab-always-indent 'complete
          tab-width 8
          tool-bar-mode nil)
  (when (eq system-type 'darwin)
    (setopt ns-alternate-modifier nil
            ns-command-modifier 'meta
            ns-right-command-modifier 'super))
  ;; Ensure to load all relevant `Org' libraries.
  (dolist (lib '(org ob-core ob-latex org-src ox-latex))
    (require lib))
  ;; Setting `org-confirm-babel-evaluate' to `nil' is DANGEROUS.
  (setopt org-adapt-indention nil
  	org-confirm-babel-evaluate nil
  	org-latex-compiler "lualatex"
          org-latex-prefer-user-labels t
          org-latex-src-block-backend 'engraved)
  ;; Install a minimum of other packages:
  ;; `engrave-faces' is absolutely necessary.
  ;; `auctex' and `pdf-tools' are nice to have.
  ;; First `pdf-tools' install may fail. FIX: exit Emacs to restart Emacs.
  (setopt package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
                             ("gnu-devel" . "https://elpa.gnu.org/devel/")
  			   ("melpa" . "https://melpa.org/packages/")
  			   ("nongnu" . "https://elpa.nongnu.org/nongnu/"))
  	package-pinned-packages '((auctex . "gnu")
  				  (engrave-faces . "gnu-devel")
  				  (pdf-tools . "melpa")))
  (dolist (pkg '(auctex engrave-faces pdf-tools))
    (unless (package-installed-p pkg)
      (package-install pkg)))
  ;; `pdf-tools' has clickable links out of the box, contrary to `docview'.
  ;; `pdf-loader-install' ensures compilation of the `epdfinfo.c' server.
  (when (fboundp 'pdf-loader-install)
    (pdf-loader-install))
#+end_src

* LaTeX preamble with page layout and float barriers
:PROPERTIES:
:CUSTOM_ID: sec:latex-preamble
:END:

The geometry in listing [[lst:latex-header]] makes that the line length in all
listings fits within the LaTeX length ~\textwidth~.  Listing [[lst:latex-header]]
also introduces float barriers to prevent floating figures and listings from
floating outside their ~[sub-][sub-]sections~.

#+caption[LaTeX preamble with page layout and float barriers]:
#+caption: LaTeX preamble with page layout and float barriers.
#+name: lst:latex-header
#+begin_src latex -n :exports code
  % BEGIN: lst:latex-header
  \usepackage{biblatex} % LaTeX compilation fails without this package.
  % PAGE LAYOUT: https://www.overleaf.com/learn/latex/Page_size_and_margins
  \usepackage{geometry}
  \usepackage{layout}
  \geometry{
    a4paper,
    total={480pt,680pt},
    top=60pt,
    left=60pt,
  }
  % FLOAT BARRIERS:
  % https://tex.stackexchange.com/questions/118662/use-placeins-for-subsections
  % Make section an implicit float barrier:
  \usepackage[section]{placeins}
  % Make subsection an implicit float barrier:
  \makeatletter
  \AtBeginDocument{%
    \expandafter\renewcommand\expandafter\subsection\expandafter{%
      \expandafter\@fb@secFB\subsection
    }%
  }
  \makeatother
  % Make subsubsection an implicit float barrier:
  \makeatletter
  \AtBeginDocument{%
    \expandafter\renewcommand\expandafter\subsubsection\expandafter{%
      \expandafter\@fb@secFB\subsubsection
    }%
  }
  % END: lst:latex-header
#+end_src

* Noweb templates
:PROPERTIES:
:CUSTOM_ID: sec:noweb-templates
:END:

Listing [[plain-engraved]], [[fixed-engraved]], [[boxed-engraved]], [[listings]], [[minted]], and
[[verbatim]] are ~noweb~ templates for listing [[ab-do-it]] and [[ab-do-it-result]].

#+caption: Noweb ~plain-engraved~ template.
#+name: plain-engraved
#+begin_src latex -n :exports code
  % Backend (PLAIN) ENGRAVED requires no packages.
#+end_src

#+caption: Noweb ~fixed-engraved~ template.
#+name: fixed-engraved
#+begin_src latex -n :exports code
  % Backend (FIXED) ENGRAVED requires no packages.
#+end_src

#+caption: Noweb ~boxed-engraved~ template.
#+name: boxed-engraved
#+begin_src latex -n :exports code
  % Backend (BOXED) ENGRAVED requires no packages.
#+end_src

#+caption: Noweb ~listings~ template.
#+name: listings
#+begin_src latex -n :exports code
  % Source block backend LISTINGS requires two packages.
  \usepackage{listings}
  \usepackage{color}
#+end_src

#+caption: Noweb ~minted~ template.
#+name: minted
#+begin_src latex -n :exports code
  % Backend MINTED requires one package.
  \usepackage{minted}
#+end_src

#+caption: Noweb ~verbatim~ template.
#+name: verbatim
#+begin_src latex -n :exports code
  % Backend VERBATIM requires no packages.
#+end_src

* Switch backend and explore an ~engraved~ export backend bug
:PROPERTIES:
:CUSTOM_ID: sec:switch-and-explore
:END:

Listing [[ab-header]], [[ab-file-as-body]], [[ab-filter]], [[ab-org-setup]], [[ab-setup]], and
[[defun-ab-do-it]], and [[ab-footer]] tangle into [[./any-backend.el]].

#+caption: Library file header.
#+name: ab-header
#+begin_src emacs-lisp -n :eval never
  ;;; any-backend.el --- demonstrate any block backend -*- lexical-binding:t -*-

  ;; Author: Gerard Vermeulen <gerard.vermeulen@posteo.net>
  ;; Version: 0.0.1

  ;; This program is distributed in the hope that it will be useful,
  ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  ;; GNU General Public License for more details.

  ;; You should have received a copy of the GNU General Public License
  ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

  ;;; Commentary:

  ;; This file is the tangled output of `any-backend.org' tailored for
  ;; use with `any-backend.el'.  Users should go to the "Export to
  ;; LaTeX" section of `any-backend.org' and execute the `ab-do-it'
  ;; source block after evaluation or installation of `any-backend.el'.

  ;;; Code:

  (require 'ox-latex)
#+end_src

#+caption[Copy file contents to an indented source block body]:
#+caption: Copy file contents to an indented source block body.
#+name: ab-file-as-body
#+begin_src emacs-lisp -n :results silent
  (defun ab-org-babel-file-as-block-body (filename)
    "Copy FILENAME contents to an indented Org Babel source block body."
    (when (file-readable-p filename)
      (let ((delete-trailing-whitespace t)
  	  (n (if org-src-preserve-indentation
  	         0 org-edit-src-content-indentation)))
        (with-temp-buffer
          (insert-file-contents filename)
          (string-rectangle (point-min) (point-max)
  		          (make-string n ?\s))
          (delete-trailing-whitespace (point-min) (point-max))
          (buffer-substring (point-min) (point-max))))))
#+end_src

#+caption[Define ~ab-org-latex-engrave-source-block-filter~]:
#+caption: Define a source block filter function.
#+name: ab-filter
#+begin_src emacs-lisp -n :results silent
  (defun ab-org-latex-engraved-source-block-filter (data _backend _info)
    "Replace \"Code\" with \"Breakable\" in non-floating DATA environments.

  Set `org-latex-engraved-preamble' to define a Breakable (non-floating)
  environment and an unbreakable Code (floating) environment."
    (unless (string-match "^\\\\DeclareTColorBox\\[\\]{Breakable}"
                          org-latex-engraved-preamble)
      (user-error
       "`org-latex-engraved-preamble' defines no `Breakable' environment"))
    (when (eq org-latex-src-block-backend 'engraved)
      ;; Transform only blocks matching at position 0.  Therefore, do
      ;; not transform blocks that are listing environments.
      (when (string-match "\\`\\\\begin{Code}\n" data)
        (setq data (replace-match "\\begin{Breakable}\n" t 'literal data))
        (if (string-match "^\\\\end{Code}\n" data)
            (setq data (replace-match "\\end{Breakable}\n" t 'literal data))
          (error "Match `^\\\\end{Code}' failure")))))
#+end_src

#+caption[Define ~ab-org-latex-setup~.]:
#+caption: Define ~ab-org-latex-setup~.
#+name: ab-org-setup
#+begin_src emacs-lisp -n :results silent
  (defun ab-org-latex-setup (how main)
    "Set `org-latex-src-block-backend' and `org-latex-toc-command'.
  HOW selects the sub-backend and MAIN selects which Org features to use."
    (cond
     ((memq how '(minted plain-engraved fixed-engraved boxed-engraved))
      (setq-local
       org-latex-toc-command
       "\\tableofcontents\\label{toc}\n\\listoflistings\n\\newpage\n"))
     ((eq how 'listings)
      (setq-local
       org-latex-toc-command
       "\\tableofcontents\\label{toc}\n\\lstlistoflistings\n\\newpage\n"))
     ((eq how 'verbatim)
      (setq-local
       org-latex-toc-command
       "\\tableofcontents\\label{toc}\n\\listoffigures\\newpage\n"))
     (t (user-error "Correct argument `%S' for `ab-setup'" how)))
    (if (memq how '(plain-engraved fixed-engraved boxed-engraved))
        (setq-local org-latex-src-block-backend 'engraved)
      (setq-local org-latex-src-block-backend how))
    (if main (setq-local org-latex-packages-alist nil)
      (setq-local org-latex-packages-alist
                  (or (and (eq how 'minted) '(("" "minted")))
                      (and (eq how 'listings) '(("" "listings")
                                                ("" "color")))))))
#+end_src

#+caption[Define ~ab-setup~]:
#+caption: Define ~ab-setup~.
#+caption: *Line 41* depends on ~how~ being ~fixed-engraved~ or ~boxed-engraved~.
#+name: ab-setup
#+begin_src emacs-lisp -n :results silent
  (defun ab-setup (how main)
    "Set `org-latex-src-block-backend', `org-latex-toc-command',
  `org-latex-engraved-preamble', and `org-export-filter-src-block-functions'.
  HOW selects the sub-backend and MAIN selects which Org features to use."
    (ab-org-latex-setup how main)
    (if (memq how '(verbatim listings minted plain-engraved))
        (progn (setq-local org-latex-engraved-preamble
                           (default-toplevel-value 'org-latex-engraved-preamble))
               (setq-local org-export-filter-src-block-functions nil))
      (setq-local org-latex-engraved-preamble
                  (format "\\usepackage{fvextra}
  [FVEXTRA-SETUP]
  %% Make code and line numbers normalsize. Make line numbers grey.
  \\renewcommand\\theFancyVerbLine{
    \\normalsize\\color{black!40!white}\\arabic{FancyVerbLine}}
  %% Do not rely on an eventual call to `engrave-faces-latex-gen-preamble'.
  \\usepackage{xcolor}
  \\providecolor{EfD}{HTML}{f7f7f7}
  \\providecolor{EFD}{HTML}{28292e}
  %% Define a breakable Code environment to prettily wrap the fontified code.
  \\usepackage[breakable,xparse]{tcolorbox}
  \\DeclareTColorBox[]{Breakable}{o}{
    colback=EfD, colframe=EFD, colupper=EFD,
    fontupper=\\normalsize\\setlength{\\fboxsep}{0pt},
    IfNoValueTF={#1}{
      boxsep=2pt, arc=2.5pt, outer arc=2.5pt, boxrule=1.0pt
    }{
      boxsep=2.5pt, arc=0pt, outer arc=0pt, boxrule=0pt, leftrule=1.5pt
    },
    left=2pt, right=2pt, top=1pt, bottom=0.5pt, breakable
  }
  %% Define an unbreakable Code environment to fontify code inside floats.
  \\DeclareTColorBox[]{Code}{o}{
    colback=EfD, colframe=EFD, colupper=EFD,
    fontupper=\\normalsize\\setlength{\\fboxsep}{0pt},
    IfNoValueTF={#1}{
      boxsep=2pt, arc=2.5pt, outer arc=2.5pt, boxrule=1.0pt
    }{
      boxsep=2.5pt, arc=0pt, outer arc=0pt, boxrule=0pt, leftrule=1pt
    },
    left=2pt, right=2pt, top=1pt, bottom=1pt, %s
  }
  [LISTINGS-SETUP]" (or (and (eq how 'fixed-engraved) "unbreakable")
                        (and (eq how 'boxed-engraved) "breakable")
                        (user-error "(ab-setup `%S') yells BOOM!" how))))
      (setq-local org-export-filter-src-block-functions
                  '(ab-org-latex-engraved-source-block-filter)))
    org-latex-src-block-backend)
#+end_src

#+caption[Define ~ab-select-how-and-export-to-latex~]:
#+caption: Define ~ab-select-how-and-export-to-latex~.
#+name: defun-ab-do-it
#+begin_src emacs-lisp -n :exports code :results silent
  ;;;###autoload
  (defun ab-select-how-and-export-to-latex (main)
    "Export Org buffer to LaTeX file after prompting how to export.
  In case MAIN is non-nil use org-9.7pre features, or in case MAIN is nil
  use org-9.16 features, to export to LaTeX.

  The `engraved' source block export backend may lead to defects in
  compiled `pdf' for floating listings where vertical line spacing may not
  be constant.  Option `plain-engraved' selects Org upstream, option
  `fixed-engraved' selects a bug work-around, and option `boxed-engraved'
  selects a bug amplification which may lead to terrible `pdf' output.
  The other choices are `verbatim', `listings', and `minted' to select the
  other backends."
    (interactive)
    (let ((how
           (intern-soft
            (completing-read
             "How: " '(plain-engraved fixed-engraved boxed-engraved
                                      verbatim listings minted)
             nil t)))
          (seconds 1))
      (ab-setup how main)
      (run-with-timer seconds nil #'org-latex-export-to-latex)
      (if main
          (format "#+latex_header: <<%s>>" how)
        (format "%% %s" how))))
#+end_src

#+caption[Library file footer]:
#+caption: Library file footer.
#+name: ab-footer
#+begin_src emacs-lisp -n :eval never
  (provide 'any-backend)

  ;;; any-backend.el ends here
#+end_src

* Export to LaTeX
:PROPERTIES:
:CUSTOM_ID: sec:any-backend-usage
:END:

Originally, I had written this document to explore ~noweb~, but that exposed a
bug fixed since ~2024-02-05~.  Execution of the listing [[ab-do-it]] source block
uses ~noweb~ in case of setting "~:var main='t~" in this source block and
execution of the listing [[ab-do-it]] source block does not use ~noweb~ in case of
setting "~:var main='nil~".  The latter setting has the effect of exporting the
body of listing [[ab-do-it-result]].

#+caption[Call ~ab-select-how-and-export-to-latex~]:
#+caption: Call ~ab-select-how-and-export-to-latex~.
#+name: ab-do-it
#+header: :var main='nil
#+header: :wrap "src latex -n :exports both :noweb yes :results raw"
#+begin_src emacs-lisp -n :exports both :results raw :eval no-export :tangle no
  (unless (or (featurep 'any-backend)
              (require 'any-backend nil 'noerror))
    (user-error "Evaluate or install `any-backend.el' (after tangling?)"))
  (ab-select-how-and-export-to-latex main)
#+end_src

#+caption[Run ~ab-select-how-and-export-to-latex~ result]:
#+caption: Run ~ab-select-how-and-export-to-latex~ result.
#+name: ab-do-it-result
#+RESULTS: ab-do-it
#+begin_src latex -n :exports both :noweb yes :results raw
% plain-engraved
#+end_src

#+RESULTS: ab-do-it-result
#+latex_header: % Backend (PLAIN) ENGRAVED requires no packages.

* Make never "broken" non-floating listing
:PROPERTIES:
:CUSTOM_ID: sec:make-non-floating-listing
:END:

#+caption[Insert ~any-backend.el~]:
#+caption: Insert ~any-backend.el~.
#+header: :wrap "src emacs-lisp -n :eval never :tangle no"
#+name: insert-non-float
#+header: :var filename="any-backend.el"
#+begin_src emacs-lisp -n :eval no-export :exports both :tangle no
  (unless (or (featurep 'any-backend)
              (require 'any-backend nil 'noerror))
    (user-error "Evaluate or install `any-backend.el' (after tangling?)"))
  (ab-org-babel-file-as-block-body filename)
#+end_src

** List never "broken" non-floating listing
:PROPERTIES:
:CUSTOM_ID: sec:list-non-floating-listing
:END:

The next non-floating listing occupies a space of more than two pages.
#+name: list-non-float-result
#+RESULTS: insert-non-float
#+begin_src emacs-lisp -n :eval never :tangle no
  ;;; any-backend.el --- demonstrate any block backend -*- lexical-binding:t -*-

  ;; Author: Gerard Vermeulen <gerard.vermeulen@posteo.net>
  ;; Version: 0.0.1

  ;; This program is distributed in the hope that it will be useful,
  ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  ;; GNU General Public License for more details.

  ;; You should have received a copy of the GNU General Public License
  ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

  ;;; Commentary:

  ;; This file is the tangled output of `any-backend.org' tailored for
  ;; use with `any-backend.el'.  Users should go to the "Export to
  ;; LaTeX" section of `any-backend.org' and execute the `ab-do-it'
  ;; source block after evaluation or installation of `any-backend.el'.

  ;;; Code:

  (require 'ox-latex)

  (defun ab-org-babel-file-as-block-body (filename)
    "Copy FILENAME contents to an indented Org Babel source block body."
    (when (file-readable-p filename)
      (let ((delete-trailing-whitespace t)
  	  (n (if org-src-preserve-indentation
  	         0 org-edit-src-content-indentation)))
        (with-temp-buffer
          (insert-file-contents filename)
          (string-rectangle (point-min) (point-max)
  		          (make-string n ?\s))
          (delete-trailing-whitespace (point-min) (point-max))
          (buffer-substring (point-min) (point-max))))))

  (defun ab-org-latex-engraved-source-block-filter (data _backend _info)
    "Replace \"Code\" with \"Breakable\" in non-floating DATA environments.

  Set `org-latex-engraved-preamble' to define a Breakable (non-floating)
  environment and an unbreakable Code (floating) environment."
    (unless (string-match "^\\\\DeclareTColorBox\\[\\]{Breakable}"
                          org-latex-engraved-preamble)
      (user-error
       "`org-latex-engraved-preamble' defines no `Breakable' environment"))
    (when (eq org-latex-src-block-backend 'engraved)
      ;; Transform only blocks matching at position 0.  Therefore, do
      ;; not transform blocks that are listing environments.
      (when (string-match "\\`\\\\begin{Code}\n" data)
        (setq data (replace-match "\\begin{Breakable}\n" t 'literal data))
        (if (string-match "^\\\\end{Code}\n" data)
            (setq data (replace-match "\\end{Breakable}\n" t 'literal data))
          (error "Match `^\\\\end{Code}' failure")))))

  (defun ab-org-latex-setup (how main)
    "Set `org-latex-src-block-backend' and `org-latex-toc-command'.
  HOW selects the sub-backend and MAIN selects which Org features to use."
    (cond
     ((memq how '(minted plain-engraved fixed-engraved boxed-engraved))
      (setq-local
       org-latex-toc-command
       "\\tableofcontents\\label{toc}\n\\listoflistings\n\\newpage\n"))
     ((eq how 'listings)
      (setq-local
       org-latex-toc-command
       "\\tableofcontents\\label{toc}\n\\lstlistoflistings\n\\newpage\n"))
     ((eq how 'verbatim)
      (setq-local
       org-latex-toc-command
       "\\tableofcontents\\label{toc}\n\\listoffigures\\newpage\n"))
     (t (user-error "Correct argument `%S' for `ab-setup'" how)))
    (if (memq how '(plain-engraved fixed-engraved boxed-engraved))
        (setq-local org-latex-src-block-backend 'engraved)
      (setq-local org-latex-src-block-backend how))
    (if main (setq-local org-latex-packages-alist nil)
      (setq-local org-latex-packages-alist
                  (or (and (eq how 'minted) '(("" "minted")))
                      (and (eq how 'listings) '(("" "listings")
                                                ("" "color")))))))

  (defun ab-setup (how main)
    "Set `org-latex-src-block-backend', `org-latex-toc-command',
  `org-latex-engraved-preamble', and `org-export-filter-src-block-functions'.
  HOW selects the sub-backend and MAIN selects which Org features to use."
    (ab-org-latex-setup how main)
    (if (memq how '(verbatim listings minted plain-engraved))
        (progn (setq-local org-latex-engraved-preamble
                           (default-toplevel-value 'org-latex-engraved-preamble))
               (setq-local org-export-filter-src-block-functions nil))
      (setq-local org-latex-engraved-preamble
                  (format "\\usepackage{fvextra}
  [FVEXTRA-SETUP]
  %% Make code and line numbers normalsize. Make line numbers grey.
  \\renewcommand\\theFancyVerbLine{
    \\normalsize\\color{black!40!white}\\arabic{FancyVerbLine}}
  %% Do not rely on an eventual call to `engrave-faces-latex-gen-preamble'.
  \\usepackage{xcolor}
  \\providecolor{EfD}{HTML}{f7f7f7}
  \\providecolor{EFD}{HTML}{28292e}
  %% Define a breakable Code environment to prettily wrap the fontified code.
  \\usepackage[breakable,xparse]{tcolorbox}
  \\DeclareTColorBox[]{Breakable}{o}{
    colback=EfD, colframe=EFD, colupper=EFD,
    fontupper=\\normalsize\\setlength{\\fboxsep}{0pt},
    IfNoValueTF={#1}{
      boxsep=2pt, arc=2.5pt, outer arc=2.5pt, boxrule=1.0pt
    }{
      boxsep=2.5pt, arc=0pt, outer arc=0pt, boxrule=0pt, leftrule=1.5pt
    },
    left=2pt, right=2pt, top=1pt, bottom=0.5pt, breakable
  }
  %% Define an unbreakable Code environment to fontify code inside floats.
  \\DeclareTColorBox[]{Code}{o}{
    colback=EfD, colframe=EFD, colupper=EFD,
    fontupper=\\normalsize\\setlength{\\fboxsep}{0pt},
    IfNoValueTF={#1}{
      boxsep=2pt, arc=2.5pt, outer arc=2.5pt, boxrule=1.0pt
    }{
      boxsep=2.5pt, arc=0pt, outer arc=0pt, boxrule=0pt, leftrule=1pt
    },
    left=2pt, right=2pt, top=1pt, bottom=1pt, %s
  }
  [LISTINGS-SETUP]" (or (and (eq how 'fixed-engraved) "unbreakable")
                        (and (eq how 'boxed-engraved) "breakable")
                        (user-error "(ab-setup `%S') yells BOOM!" how))))
      (setq-local org-export-filter-src-block-functions
                  '(ab-org-latex-engraved-source-block-filter)))
    org-latex-src-block-backend)

  ;;;###autoload
  (defun ab-select-how-and-export-to-latex (main)
    "Export Org buffer to LaTeX file after prompting how to export.
  In case MAIN is non-nil use org-9.7pre features, or in case MAIN is nil
  use org-9.16 features, to export to LaTeX.

  The `engraved' source block export backend may lead to defects in
  compiled `pdf' for floating listings where vertical line spacing may not
  be constant.  Option `plain-engraved' selects Org upstream, option
  `fixed-engraved' selects a bug work-around, and option `boxed-engraved'
  selects a bug amplification which may lead to terrible `pdf' output.
  The other choices are `verbatim', `listings', and `minted' to select the
  other backends."
    (interactive)
    (let ((how
           (intern-soft
            (completing-read
             "How: " '(plain-engraved fixed-engraved boxed-engraved
                                      verbatim listings minted)
             nil t)))
          (seconds 1))
      (ab-setup how main)
      (run-with-timer seconds nil #'org-latex-export-to-latex)
      (if main
          (format "#+latex_header: <<%s>>" how)
        (format "%% %s" how))))

  (provide 'any-backend)

  ;;; any-backend.el ends here
#+end_src
The previous non-floating listing occupies a space of more than two pages.

* Conclusion: summary of constraints and limitations
:PROPERTIES:
:CUSTOM_ID: sec:conclusion
:END:

1. Placement of floating listings:
   - It is impossible to have more than three floating listings on a page,
     neither with ~minted~ nor with ~engraved~.
   - Float barriers help to control the placement of floating listing.
   - Mixing floating and non-floating listings in the same ~[sub-][sub-]section~
     gives visually weird results: floating listings may float between the parts
     of non-floating listings.
2. Table of contents:
   - the ~verbatim~ backend produces a "List of Figures" instead of a "List of
     Listings".
3. Sub-backend ~plain-engraved~ moving target defects:
   - Listing [[plain-engraved]] is in a botched state.
   - Listing [[ab-filter]] shows too much vertical spacing after line 13.
   - Listing [[ab-org-setup]] shows too much vertical spacing after line 13.
   - Listing [[ab-setup]] shows too much vertical spacing after line 13, 26, and 39.
   - Listing [[defun-ab-do-it]] shows too much vertical spacing after line 13.
4. Sub-backend ~boxed-engraved~ moving target defects:
   - Listing [[ab-org-setup]] shows too much vertical spacing after line 19.
   - Listing [[ab-setup]] shows too much vertical spacing after line 19, and 38.
   - Listing [[defun-ab-do-it]] shows too much vertical spacing after line 19.
*Fixing ~engraved~ requires:*
1. ~unbreakable~ floating listings.
2. ~\normalsize~ font size.
3. visible boxes.
Points (2) and (3) are unacceptable, IMO.

# Emacs looks for "Local variables:" after the last "newline-formfeed".
\f
# Local Variables:
# compile-command: "latexmk -interaction=nonstopmode -lualatex -pvc -shell-escape any-backend.tex"
# fill-column: 80
# org-edit-src-content-indentation: 2
# End:

[-- Attachment #3: any-backend.el --]
[-- Type: application/octet-stream, Size: 6886 bytes --]

;;; any-backend.el --- demonstrate any block backend -*- lexical-binding:t -*-

;; Author: Gerard Vermeulen <gerard.vermeulen@posteo.net>
;; Version: 0.0.1

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This file is the tangled output of `any-backend.org' tailored for
;; use with `any-backend.el'.  Users should go to the "Export to
;; LaTeX" section of `any-backend.org' and execute the `ab-do-it'
;; source block after evaluation or installation of `any-backend.el'.

;;; Code:

(require 'ox-latex)

(defun ab-org-babel-file-as-block-body (filename)
  "Copy FILENAME contents to an indented Org Babel source block body."
  (when (file-readable-p filename)
    (let ((delete-trailing-whitespace t)
	  (n (if org-src-preserve-indentation
	         0 org-edit-src-content-indentation)))
      (with-temp-buffer
        (insert-file-contents filename)
        (string-rectangle (point-min) (point-max)
		          (make-string n ?\s))
        (delete-trailing-whitespace (point-min) (point-max))
        (buffer-substring (point-min) (point-max))))))

(defun ab-org-latex-engraved-source-block-filter (data _backend _info)
  "Replace \"Code\" with \"Breakable\" in non-floating DATA environments.

Set `org-latex-engraved-preamble' to define a Breakable (non-floating)
environment and an unbreakable Code (floating) environment."
  (unless (string-match "^\\\\DeclareTColorBox\\[\\]{Breakable}"
                        org-latex-engraved-preamble)
    (user-error
     "`org-latex-engraved-preamble' defines no `Breakable' environment"))
  (when (eq org-latex-src-block-backend 'engraved)
    ;; Transform only blocks matching at position 0.  Therefore, do
    ;; not transform blocks that are listing environments.
    (when (string-match "\\`\\\\begin{Code}\n" data)
      (setq data (replace-match "\\begin{Breakable}\n" t 'literal data))
      (if (string-match "^\\\\end{Code}\n" data)
          (setq data (replace-match "\\end{Breakable}\n" t 'literal data))
        (error "Match `^\\\\end{Code}' failure")))))

(defun ab-org-latex-setup (how main)
  "Set `org-latex-src-block-backend' and `org-latex-toc-command'.
HOW selects the sub-backend and MAIN selects which Org features to use."
  (cond
   ((memq how '(minted plain-engraved fixed-engraved boxed-engraved))
    (setq-local
     org-latex-toc-command
     "\\tableofcontents\\label{toc}\n\\listoflistings\n\\newpage\n"))
   ((eq how 'listings)
    (setq-local
     org-latex-toc-command
     "\\tableofcontents\\label{toc}\n\\lstlistoflistings\n\\newpage\n"))
   ((eq how 'verbatim)
    (setq-local
     org-latex-toc-command
     "\\tableofcontents\\label{toc}\n\\listoffigures\\newpage\n"))
   (t (user-error "Correct argument `%S' for `ab-setup'" how)))
  (if (memq how '(plain-engraved fixed-engraved boxed-engraved))
      (setq-local org-latex-src-block-backend 'engraved)
    (setq-local org-latex-src-block-backend how))
  (if main (setq-local org-latex-packages-alist nil)
    (setq-local org-latex-packages-alist
                (or (and (eq how 'minted) '(("" "minted")))
                    (and (eq how 'listings) '(("" "listings")
                                              ("" "color")))))))

(defun ab-setup (how main)
  "Set `org-latex-src-block-backend', `org-latex-toc-command',
`org-latex-engraved-preamble', and `org-export-filter-src-block-functions'.
HOW selects the sub-backend and MAIN selects which Org features to use."
  (ab-org-latex-setup how main)
  (if (memq how '(verbatim listings minted plain-engraved))
      (progn (setq-local org-latex-engraved-preamble
                         (default-toplevel-value 'org-latex-engraved-preamble))
             (setq-local org-export-filter-src-block-functions nil))
    (setq-local org-latex-engraved-preamble
                (format "\\usepackage{fvextra}
[FVEXTRA-SETUP]
%% Make code and line numbers normalsize. Make line numbers grey.
\\renewcommand\\theFancyVerbLine{
  \\normalsize\\color{black!40!white}\\arabic{FancyVerbLine}}
%% Do not rely on an eventual call to `engrave-faces-latex-gen-preamble'.
\\usepackage{xcolor}
\\providecolor{EfD}{HTML}{f7f7f7}
\\providecolor{EFD}{HTML}{28292e}
%% Define a breakable Code environment to prettily wrap the fontified code.
\\usepackage[breakable,xparse]{tcolorbox}
\\DeclareTColorBox[]{Breakable}{o}{
  colback=EfD, colframe=EFD, colupper=EFD,
  fontupper=\\normalsize\\setlength{\\fboxsep}{0pt},
  IfNoValueTF={#1}{
    boxsep=2pt, arc=2.5pt, outer arc=2.5pt, boxrule=1.0pt
  }{
    boxsep=2.5pt, arc=0pt, outer arc=0pt, boxrule=0pt, leftrule=1.5pt
  },
  left=2pt, right=2pt, top=1pt, bottom=0.5pt, breakable
}
%% Define an unbreakable Code environment to fontify code inside floats.
\\DeclareTColorBox[]{Code}{o}{
  colback=EfD, colframe=EFD, colupper=EFD,
  fontupper=\\normalsize\\setlength{\\fboxsep}{0pt},
  IfNoValueTF={#1}{
    boxsep=2pt, arc=2.5pt, outer arc=2.5pt, boxrule=1.0pt
  }{
    boxsep=2.5pt, arc=0pt, outer arc=0pt, boxrule=0pt, leftrule=1pt
  },
  left=2pt, right=2pt, top=1pt, bottom=1pt, %s
}
[LISTINGS-SETUP]" (or (and (eq how 'fixed-engraved) "unbreakable")
                      (and (eq how 'boxed-engraved) "breakable")
                      (user-error "(ab-setup `%S') yells BOOM!" how))))
    (setq-local org-export-filter-src-block-functions
                '(ab-org-latex-engraved-source-block-filter)))
  org-latex-src-block-backend)

;;;###autoload
(defun ab-select-how-and-export-to-latex (main)
  "Export Org buffer to LaTeX file after prompting how to export.
In case MAIN is non-nil use org-9.7pre features, or in case MAIN is nil
use org-9.16 features, to export to LaTeX.

The `engraved' source block export backend may lead to defects in
compiled `pdf' for floating listings where vertical line spacing may not
be constant.  Option `plain-engraved' selects Org upstream, option
`fixed-engraved' selects a bug work-around, and option `boxed-engraved'
selects a bug amplification which may lead to terrible `pdf' output.
The other choices are `verbatim', `listings', and `minted' to select the
other backends."
  (interactive)
  (let ((how
         (intern-soft
          (completing-read
           "How: " '(plain-engraved fixed-engraved boxed-engraved
                                    verbatim listings minted)
           nil t)))
        (seconds 1))
    (ab-setup how main)
    (run-with-timer seconds nil #'org-latex-export-to-latex)
    (if main
        (format "#+latex_header: <<%s>>" how)
      (format "%% %s" how))))

(provide 'any-backend)

;;; any-backend.el ends here

[-- Attachment #4: any-backend.pdf --]
[-- Type: application/pdf, Size: 85057 bytes --]

[-- Attachment #5: 0001-Unacceptable-engraved-backend-fix.patch --]
[-- Type: application/octet-stream, Size: 3924 bytes --]

From 211db75966232616e43af55672edd78d114172e0 Mon Sep 17 00:00:00 2001
From: Gerard Vermeulen <gerard.vermeulen@posteo.net>
Date: Wed, 14 Feb 2024 18:41:42 +0100
Subject: [PATCH] Unacceptable engraved backend fix

This fixes the unbreakable/breakable for floating/non-floating
listings, but it also requires normalsize font size and visible boxes
around the listings.  This makes the patch unacceptable for general
use.
---
 lisp/ox-latex.el | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index cfa2b8178..6bffe7f1c 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1190,7 +1190,8 @@ will produce
 [FVEXTRA-SETUP]
 
 % Make line numbers smaller and grey.
-\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
+\\renewcommand\\theFancyVerbLine{
+  \\normalsize\\color{black!40!white}\\arabic{FancyVerbLine}}
 
 \\usepackage{xcolor}
 
@@ -1200,17 +1201,13 @@ will produce
 
 % Define a Code environment to prettily wrap the fontified code.
 \\usepackage[breakable,xparse]{tcolorbox}
-\\DeclareTColorBox[]{Code}{o}%
-{colback=EfD!98!EFD, colframe=EfD!95!EFD,
-  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
-  colupper=EFD,
-  IfNoValueTF={#1}%
-  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
-    boxrule=0.5pt, left=2pt}%
-  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
-    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
-  right=2pt, top=1pt, bottom=0.5pt,
-  breakable}
+\\DeclareTColorBox[]{Code}{s}{
+  colback=EfD, colframe=EFD, colupper=EFD,
+  fontupper=\\normalsize\\setlength{\\fboxsep}{0pt},
+  boxsep=2pt, arc=2.5pt, outer arc=2.5pt, boxrule=0.5pt,
+  IfNoValueTF={#1}{unbreakable}{breakable},
+  left=2pt, right=2pt, top=1pt, bottom=0.5pt
+}
 
 [LISTINGS-SETUP]"
   "Preamble content injected when using engrave-faces-latex for source blocks.
@@ -3530,13 +3527,18 @@ and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
       (when (eq mathescape 'yes)
         (or engrave-faces-latex-mathescape t)))))
 
-(defun org-latex-src--engrave-code (content lang &optional theme options inline)
+(defun org-latex-src--engrave-code
+    (content lang &optional theme options inline caption)
   "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result.
 When the THEME symbol is non-nil, that theme will be used.
 
 When INLINE is nil, a Verbatim environment wrapped in a Code
 environment will be used. When t, a Verb command will be used.
 
+When CAPTION is nil, make a breakable Code environment for non-floating
+listings. Otherwise, make an unbreakable Code environment for floating
+listings.
+
 When OPTIONS is provided, as either a string or list of key-value
 pairs accepted by `org-latex--make-option-string', it is passed
 to the Verbatim environment or Verb command."
@@ -3568,7 +3570,10 @@ to the Verbatim environment or Verb command."
              (engraved-wrapped
               (if inline
                   (concat "\\Verb" engraved-options "{" engraved-code "}")
-                (concat "\\begin{Code}\n\\begin{Verbatim}" engraved-options "\n"
+                ;; IME, only caption determines float or non-float.
+                (concat (if caption "\\begin{Code}\n\\begin{Verbatim}"
+                          "\\begin{Code}*\n\\begin{Verbatim}")
+                        engraved-options "\n"
                         engraved-code "\n\\end{Verbatim}\n\\end{Code}"))))
         (kill-buffer engraved-buffer)
         (if theme
@@ -3637,7 +3642,7 @@ and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
             (org-latex-src--engrave-code
              content lang
              (when engraved-theme (intern engraved-theme))
-             options))))
+             options nil caption))))
     (concat (car float-env) body (cdr float-env))))
 
 (cl-defun org-latex-src-block--listings
-- 
2.42.0


^ permalink raw reply related	[relevance 17%]

* figures not exported properly by ox-latex
@ 2024-02-02 11:39  8% mahmood sheikh
  2024-07-09 20:15  0% ` Karthik Chikmagalur
  0 siblings, 1 reply; 200+ results
From: mahmood sheikh @ 2024-02-02 11:39 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 612 bytes --]

im on tecosaur's dev branch (version 9.7-pre)
i have the following in an org file:
```org
#+name: fig-switching-circuit-1
#+caption: implementation of \(p\)
[[attachment:circuit.svg]]
```
it gets turned into this
```
\includesvg[width=.9\linewidth]{/home/mahmooz/brain/notes/data/9e/5ba2ce-c383-4396-a2cb-891465f14d51/circuit}\\[0pt]
```
which isnt the behavior described in the docs:
> When captions follow the method as described in Captions, the LaTeX
export back-end wraps the picture in a floating ‘figure’ environment.
this is from https://orgmode.org/manual/Images-in-LaTeX-export.html

[-- Attachment #2: Type: text/html, Size: 788 bytes --]

^ permalink raw reply	[relevance 8%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-21  5:44  9%       ` Max Nikulin
@ 2024-01-31 15:09  9%         ` Ihor Radchenko
  0 siblings, 0 replies; 200+ results
From: Ihor Radchenko @ 2024-01-31 15:09 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode, Juan Manuel Macías

Max Nikulin <manikulin@gmail.com> writes:

>>> I would suggest to strip leading and trailing newlines before processing
>>> of the block content.
>> 
>> May you elaborate?
>
> I expect that
>
> #+BEGIN_VERSE
>
>
>  From fairest creatures we desire increase,
> That thereby beauty’s rose might never die,
>
>
>
> #+END_VERSE
>
> is exported to
>
> \begin{verse}
>  From fairest creatures we desire increase,\\
> That thereby beauty’s rose might never die,
> \end{verse}
>
> and internally at some point it is represented as
> "From fairest creatures we desire increase,\nThat thereby beauty’s rose 
> might never die,"
> without leading and trailing newlines.

This has nothing to do with what happens when exporting verse blocks.

If you try a simple example like

#+options: toc:nil
* Heading
First.

Foo
#+BEGIN_VERSE

 From fairest creatures we desire increase,
That thereby beauty’s rose might never die,

#+END_VERSE
Bar

Foo
#+BEGIN_VERSE
 From fairest creatures we desire increase,
That thereby beauty’s rose might never die,
#+END_VERSE
Bar

you will see that lading and trailing spaces are insignificant:

\section{Heading}
\label{sec:orgc54e19b}
First.

Foo
\begin{verse}
\hspace*{1\fontdimen2\font}From fairest creatures we desire increase,\\
That thereby beauty’s rose might never die,\\
\end{verse}
Bar

Foo
\begin{verse}
\hspace*{1\fontdimen2\font}From fairest creatures we desire increase,\\
That thereby beauty’s rose might never die,\\
\end{verse}
Bar

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 9%]

* Re: An academic journal entirely made in Org-Mode
  @ 2024-01-31 14:30  4%   ` Juan Manuel Macías
  0 siblings, 0 replies; 200+ results
From: Juan Manuel Macías @ 2024-01-31 14:30 UTC (permalink / raw)
  To: Dr. Arne Babenhauserheide; +Cc: emacs-orgmode

Hi, Arne, thank you for your comments.

Dr. Arne Babenhauserheide writes:

> Hi,
>
> Juan Manuel Macías <maciaschain@posteo.net> writes:
>
>> Org-Publish and LuaTeX. If anyone is interested in the code I used for
>> specific aspects of the publication, I can share it here :-).
>
> That sounds very interesting! I’m writing roleplaying books and my
> website with org-mode and since there are many small pieces I found over
> the years, I expect that the solved problems for a journal will be very
> educational!

I am currently responsible for the production of five academic journals,
and I have ended up developing a fairly productive workflow using
org/luatex. A little background on the matter: in my editorial design
work I used to work only in (La)TeX, but I discovered that org can
function as a fairly competent high-level interface to LaTeX. One of the
main advantages is the clarity that a light markup language brings to
the content, since pure LaTeX code is cumbersome. I know LaTeX code
reasonably well (in fact, I'm working on a couple of packages for
LuaLaTeX), but it's not comfortable for me to work on content.
Naturally, for heavy and complex jobs, post-processing is always
necessary. Org is still very useful as it is not only a lightweight
markup language but also a set of tools. And, loosely speaking, a work
environment on Emacs (which in itself is a work environment).

The main challenge of this workflow is obtaining the content, the data,
from the Word documents that the authors deliver, since, unfortunately,
everyone uses Word. Pandoc does a good job, as long as the Word
documents arrive reasonably well structured. Unfortunately, this is not
the case, at least in Humanities. Word documents usually have the
following defects:

- abuse of direct format; 

- absence of applied styles, therefore it is impossible to obtain a
  hierarchical outline of the document;

- absence of an automated system of bibliographies and citations.
  Humanities authors don't even use "friendly" things like Zotero. That
  is, Humanities authors make citations and bibliographies by hand (!!),
  which means multiplying inconsistencies and typos.

Therefore, it is necessary to subject the original Word documents to a
cleaning process. Then I run pandoc using some templates and some custom
lua filters.

The journal is basically an org-publish project, where only the articles
and other parts are exported to *.tex files. There is a master document
that I export and compile using a function that runs latexmk in
interactive mode. This way I have more control over the parts, I can
deactivate nodes, etc. Each node, therefore, is an article, with a
series of properties: author, email, orcid-id, doi, title in English,
etc. In a sty document created ad hoc I have defined a series of LaTeX
variables, and then incorporated them into each heading. E.g.:

#+begin_src latex
  \def\@author{}
  \newcommand\author[1]{\def\@author{#1}}
  \def\@mail{}
  \newcommand\mail[1]{\def\@mail{#1}}
  \def\@doi{}
  \newcommand\doi[1]{\def\@doi{DOI: #1}}

etc...
#+end_src

I use org-capture to populate the nodes in the master document with all
that information.

>> https://recyt.fecyt.es/index.php/rel/issue/view/4327/948
>
> One small thing: the boxes for the abstract look pretty nice! How to
> create the complex tables on page 109ff would also be great to know.

The boxes are made with the mdframed package, which is very versatile for this type of
objets. The code used:

#+begin_src latex
\usepackage[framemethod=tikz,everyline=true]{mdframed}
#+end_src

A box style:

#+begin_src latex
  \colorlet{background}{gray!7}

  \mdfdefinestyle{mdabstracts}{%
    linewidth=.3pt,
    topline = true,
    leftline =true,
    rightline = true,
    bottomline = true,
    skipabove=0pt,
    skipbelow=2\bigskipamount, 
    leftmargin=0em,
    backgroundcolor=background,
    roundcorner = 5pt,
    innerleftmargin=1.5em,
    rightmargin=0em,
    innerrightmargin=1.5em,
    innertopmargin=1em,
    splittopskip=\topskip,
    innerbottommargin=1em,
  }
#+end_src

And an environment:

#+begin_src latex
  \newmdenv[style=mdabstracts]{abstracts}
#+end_src

As for tables, I always try to apply the ideas of Edward Tufte. I use the booktabs package
with some modifications. An example of a table:

https://i.imgur.com/70NtdGb.png

Here I use these two macros:

#+macro: cmd @@latex:\cmidrule(rl){$1}@@
#+macro: mc @@latex:\multicolumn{$1}{$2}{$3}@@

And this filter for multicolumn rows (simply, the cells that contain "!!" are removed:

#+BIND: org-export-filter-table-functions (my-multicolumn-filter)
#+begin_src emacs-lisp :exports results :results none
  (defun my-multicolumn-flilter (texto backend info)
    (when (org-export-derived-backend-p backend 'latex)
      (replace-regexp-in-string "&\s+!!" "" texto)))
#+end_src

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 4%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-21 13:42 35%                                     ` Ihor Radchenko
  2024-01-21 19:25  9%                                       ` Juan Manuel Macías
@ 2024-01-31 11:39 10%                                       ` Ihor Radchenko
  1 sibling, 0 replies; 200+ results
From: Ihor Radchenko @ 2024-01-31 11:39 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode, Max Nikulin

Ihor Radchenko <yantar92@posteo.net> writes:

> Given that `org-latex-line-break-safe' also introduced the problem with
> verse blocks, I decided that it is better to remove it at the end.
>
> See the attached tentative patchset.

Applied, onto main.
https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=03b383df8

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 10%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-21 13:42 35%                                     ` Ihor Radchenko
@ 2024-01-21 19:25  9%                                       ` Juan Manuel Macías
  2024-01-31 11:39 10%                                       ` Ihor Radchenko
  1 sibling, 0 replies; 200+ results
From: Juan Manuel Macías @ 2024-01-21 19:25 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode, Max Nikulin

Ihor Radchenko writes:

> Upon looking closer into selective removal, it turned out to be more
> tricky than I thought. I'm afraid that using \\[0pt] only in some places
> may become a bit of headache to maintain - we may accidentally break
> certain regexp replacements in `org-latex-verse-block'. In particular,
> when verse contents is not straightforward and uses \\[0pt].
>
> Given that `org-latex-line-break-safe' also introduced the problem with
> verse blocks, I decided that it is better to remove it at the end.

LaTeX code generated without org-latex-line-break-safe is much cleaner.
The decision to make this variable obsolete seems correct to me, if
there is already a better and more discreet solution. I don't know if it
will cause many problems with custom settings and filters written in
relation to this variable, as Maxim commented in a previous email... I
hope not. I have a couple of filters written already, but I don't think
it will take much work for me to readjust them.

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 9%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 20:27 18%                                   ` Juan Manuel Macías
@ 2024-01-21 13:42 35%                                     ` Ihor Radchenko
  2024-01-21 19:25  9%                                       ` Juan Manuel Macías
  2024-01-31 11:39 10%                                       ` Ihor Radchenko
  0 siblings, 2 replies; 200+ results
From: Ihor Radchenko @ 2024-01-21 13:42 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode, Max Nikulin

[-- Attachment #1: Type: text/plain, Size: 1386 bytes --]

Juan Manuel Macías <maciaschain@posteo.net> writes:

>> Although I am still a bit hesitant to remove
>> `org-latex-line-break-safe'.
>> What would be the benefit of removing it? For now, I mostly just see
>> that it will make the life harder for users in Scenario B.
>
> It's a complicated situation, because we now have two solutions to the
> same problem... It certainly sounds a bit abrupt to remove
> org-latex-line-break-safe (at least for now). I see no problem in both
> solutions coexisting. After all, the user can always give an "\\\\"
> value to org-latex-line-break-safe. The other possibility is that
> org-latex-line-break-safe is selectively deleted, as you mentioned in a
> previous email. In tables and verse blocks, unless I'm missing
> something, I think adding [0pt] would be unnecessary, with the new
> solution.

Upon looking closer into selective removal, it turned out to be more
tricky than I thought. I'm afraid that using \\[0pt] only in some places
may become a bit of headache to maintain - we may accidentally break
certain regexp replacements in `org-latex-verse-block'. In particular,
when verse contents is not straightforward and uses \\[0pt].

Given that `org-latex-line-break-safe' also introduced the problem with
verse blocks, I decided that it is better to remove it at the end.

See the attached tentative patchset.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: v2-0001-ox-latex-Make-sure-that-text-is-not-misinterprete.patch --]
[-- Type: text/x-patch, Size: 2518 bytes --]

From d2e74cc2734eaf8d782f5acf66b11956d6ffa47e Mon Sep 17 00:00:00 2001
Message-ID: <d2e74cc2734eaf8d782f5acf66b11956d6ffa47e.1705844367.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Thu, 18 Jan 2024 14:01:32 +0100
Subject: [PATCH v2 1/2] ox-latex: Make sure that [text] is not misinterpreted
 as LaTeX argument

* lisp/ox-latex.el (org-latex-plain-text): Protect plain text starting
from [.  It might be misinterpreted as optional command argument if
previous exported fragment ends with a command accepting such.
*
testing/lisp/test-ox-latex.el (text-ox-latex/protect-square-brackets):
Add new test.

Link: https://orgmode.org/list/87o7dju9vn.fsf@posteo.net
---
 lisp/ox-latex.el              |  9 +++++++++
 testing/lisp/test-ox-latex.el | 23 +++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index df20345f8..a64dd5a87 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3095,6 +3095,15 @@ (defun org-latex-plain-text (text info)
 		    "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n"
                     (concat org-latex-line-break-safe "\n")
                     output nil t)))
+    ;; Protect [foo] at the beginning of lines / beginning of the
+    ;; plain-text object.  This prevents LaTeX from unexpectedly
+    ;; interpreting @@latex:\pagebreak@@ [foo] as a command with
+    ;; optional argument.
+    (setq output (replace-regexp-in-string
+                  (rx bol (0+ space) (group "["))
+                  "{[}"
+                  output
+                  nil nil 1))
     ;; Return value.
     output))
 
diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el
index 41df1b823..237ad97ec 100644
--- a/testing/lisp/test-ox-latex.el
+++ b/testing/lisp/test-ox-latex.el
@@ -29,6 +29,29 @@ (unless (featurep 'ox-latex)
 
 \f
 
+(ert-deftest text-ox-latex/protect-square-brackets ()
+  "Test [foo] being interpreted as plain text even after LaTeX commands."
+  (org-test-with-exported-text
+      'latex
+      "* This is test
+lorem @@latex:\\pagebreak@@ [ipsum]
+
+#+begin_figure
+[lorem] figure
+#+end_figure
+
+| [foo] | 2 |
+| [bar] | 3 |
+
+- [bax]
+- [aur]
+"
+    (goto-char (point-min))
+    (should (search-forward "lorem \\pagebreak {[}ipsum]"))
+    (should (search-forward "{[}lorem] figure"))
+    (should (search-forward "{[}foo]"))
+    (should (search-forward "\\item {[}bax]"))))
+
 (ert-deftest test-ox-latex/verse ()
   "Test verse blocks."
   (org-test-with-exported-text
-- 
2.43.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: v2-0002-ox-latex-Remove-org-latex-line-break-safe.patch --]
[-- Type: text/x-patch, Size: 11526 bytes --]

From dd4618b31dc5070d6802e484fd58cf50f5d3606d Mon Sep 17 00:00:00 2001
Message-ID: <dd4618b31dc5070d6802e484fd58cf50f5d3606d.1705844367.git.yantar92@posteo.net>
In-Reply-To: <d2e74cc2734eaf8d782f5acf66b11956d6ffa47e.1705844367.git.yantar92@posteo.net>
References: <d2e74cc2734eaf8d782f5acf66b11956d6ffa47e.1705844367.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Sun, 21 Jan 2024 14:21:33 +0100
Subject: [PATCH v2 2/2] ox-latex: Remove org-latex-line-break-safe

This reverts commit 3f60acff7717e472d06833e9cf9fff6ca3d59337 and
subsequent relevant comments.

* lisp/ox-latex.el (org-latex-line-break-safe): Remove constant.  The
\\[0pt] is actually not safe to use in some scenarios. We use a
different approach to avoid plain text [...] being interpreted as
LaTeX optional argument - we escape [ like {[}; that's what pandoc
does.
(org-latex-clock):
(org-latex-line-break):
(org-latex-plain-text):
(org-latex-planning):
(org-latex--org-table):
(org-latex--math-table):
(org-latex-table-row):
(org-latex-verse-block):
* testing/lisp/test-org-table.el (test-org-table/to-latex):
* testing/lisp/test-ox-latex.el (test-ox-latex/verse):
(test-ox-latex/longtable): Remove references to
`org-latex-line-break-safe'.
* etc/ORG-NEWS (=ox-latex=: ~org-latex-line-break-safe~ is removed):
Announce removal.
* lisp/org-compat.el (org-latex-line-break-safe): Make obsolete.

Link: https://orgmode.org/list/878r4jg37s.fsf@posteo.net
---
 etc/ORG-NEWS                   | 10 +++++++
 lisp/org-compat.el             | 18 +++++++++++++
 lisp/ox-latex.el               | 49 ++++++++++++----------------------
 testing/lisp/test-org-table.el |  6 ++---
 testing/lisp/test-ox-latex.el  | 16 +++++------
 5 files changed, 56 insertions(+), 43 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 847ddf614..46f1e66a7 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -13,6 +13,16 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
 
 * Version 9.7 (not released yet)
 ** Important announcements and breaking changes
+*** =ox-latex=: ~org-latex-line-break-safe~ is removed
+
+~org-latex-line-break-safe~ constant was previously introduced to deal
+with edge cases when LaTeX interprets [...] as LaTeX command
+argument.  However, it caused a number of other issues and proved
+itself not to be as "safe" as it supposed to be.
+
+We now use a Pandoc's approach to deal with the same problem,
+utilizing ={[}= to escape =[...]= instances where needed.
+
 *** ~org-agenda-search-headline-for-time~ now ignores all the timestamp in headings
 
 Previously, ~org-agenda-search-headline-for-time~ made Org agenda
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index 17f07db9d..27d094b07 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -629,6 +629,24 @@ (define-obsolete-variable-alias 'org-reveal-start-hook
 (define-obsolete-function-alias 'org-file-url-p 'org-url-p "9.6")
 (define-obsolete-variable-alias 'org-plantuml-executable-args 'org-plantuml-args
   "Org 9.6")
+
+(defconst org-latex-line-break-safe "\\\\[0pt]"
+  "Linebreak protecting the following [...].
+
+Without \"[0pt]\" it would be interpreted as an optional argument to
+the \\\\.
+
+This constant, for example, makes the below code not err:
+
+\\begin{tabular}{c|c}
+    [t] & s\\\\[0pt]
+    [I] & A\\\\[0pt]
+    [m] & kg
+\\end{tabular}")
+(make-obsolete 'org-latex-line-break-safe
+               "should not be used - it is not safe in all the scenarios."
+               "9.7")
+
 (defun org-in-fixed-width-region-p ()
   "Non-nil if point in a fixed-width region."
   (save-match-data
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index a64dd5a87..d6e74cb45 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -298,23 +298,10 @@ (defconst org-latex-language-alist
 - `:script-tag' the script otf tag.")
 
 
-(defconst org-latex-line-break-safe "\\\\[0pt]"
-  "Linebreak protecting the following [...].
 
-Without \"[0pt]\" it would be interpreted as an optional argument to
-the \\\\.
-
-This constant, for example, makes the below code not err:
-
-\\begin{tabular}{c|c}
-    [t] & s\\\\[0pt]
-    [I] & A\\\\[0pt]
-    [m] & kg
-\\end{tabular}")
-
-(defconst org-latex-table-matrix-macros `(("bordermatrix" . "\\cr")
+(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr")
 					  ("qbordermatrix" . "\\cr")
-					  ("kbordermatrix" . ,org-latex-line-break-safe))
+					  ("kbordermatrix" . "\\\\"))
   "Alist between matrix macros and their row ending.")
 
 (defconst org-latex-math-environments-re
@@ -2124,7 +2111,7 @@ (defun org-latex-clock (clock _contents info)
 	   (concat (org-timestamp-translate (org-element-property :value clock))
 		   (let ((time (org-element-property :duration clock)))
 		     (and time (format " (%s)" time)))))
-   org-latex-line-break-safe))
+   "\\\\"))
 
 
 ;;;; Code
@@ -2722,7 +2709,7 @@ ;;;; Line Break
 (defun org-latex-line-break (_line-break _contents _info)
   "Transcode a LINE-BREAK object from Org to LaTeX.
 CONTENTS is nil.  INFO is a plist holding contextual information."
-  (concat org-latex-line-break-safe "\n"))
+  "\\\\\n")
 
 
 ;;;; Link
@@ -3092,9 +3079,7 @@ (defun org-latex-plain-text (text info)
     ;; Handle break preservation if required.
     (when (plist-get info :preserve-breaks)
       (setq output (replace-regexp-in-string
-		    "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n"
-                    (concat org-latex-line-break-safe "\n")
-                    output nil t)))
+		    "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n" output nil t)))
     ;; Protect [foo] at the beginning of lines / beginning of the
     ;; plain-text object.  This prevents LaTeX from unexpectedly
     ;; interpreting @@latex:\pagebreak@@ [foo] as a command with
@@ -3139,7 +3124,7 @@ (defun org-latex-planning (planning _contents info)
 		(format (plist-get info :latex-active-timestamp-format)
 			(org-timestamp-translate scheduled)))))))
     " ")
-   org-latex-line-break-safe))
+   "\\\\"))
 
 
 ;;;; Property Drawer
@@ -3919,11 +3904,11 @@ (defun org-latex--org-table (table contents info)
 		(format "\\begin{%s}%s{%s}\n" table-env width alignment)
 		(and above?
 		     (org-string-nw-p caption)
-		     (concat caption org-latex-line-break-safe "\n"))
+		     (concat caption "\\\\\n"))
 		contents
 		(and (not above?)
 		     (org-string-nw-p caption)
-		     (concat caption org-latex-line-break-safe "\n"))
+		     (concat caption "\\\\\n"))
 		(format "\\end{%s}" table-env)
 		(and fontsize "}"))))
      (t
@@ -4008,7 +3993,7 @@ (defun org-latex--math-table (table info)
 		 (lambda (cell)
 		   (substring (org-element-interpret-data cell) 0 -1))
 		 (org-element-map row 'table-cell #'identity info) "&")
-		(or (cdr (assoc env org-latex-table-matrix-macros)) org-latex-line-break-safe)
+		(or (cdr (assoc env org-latex-table-matrix-macros)) "\\\\")
 		"\n")))
 	   (org-element-map table 'table-row #'identity info) "")))
     (concat
@@ -4083,7 +4068,7 @@ (defun org-latex-table-row (table-row contents info)
             (setq table-head-cache (make-hash-table :test #'eq))
             (plist-put info :org-latex-table-head-cache table-head-cache))
           (if-let ((head-contents (gethash (org-element-parent table-row) table-head-cache)))
-              (puthash (org-element-parent table-row) (concat head-contents org-latex-line-break-safe "\n" contents)
+              (puthash (org-element-parent table-row) (concat head-contents "\\\\\n" contents)
                        table-head-cache)
             (puthash (org-element-parent table-row) contents table-head-cache))))
       ;; Return LaTeX string as the transcoder.
@@ -4092,7 +4077,7 @@ (defun org-latex-table-row (table-row contents info)
        ;; hline was specifically marked.
        (and booktabsp (not (org-export-get-previous-element table-row info))
 	    "\\toprule\n")
-       contents org-latex-line-break-safe "\n"
+       contents "\\\\\n"
        (cond
 	;; Special case for long tables.  Define header and footers.
 	((and longtablep (org-export-table-row-ends-header-p table-row info))
@@ -4100,9 +4085,9 @@ (defun org-latex-table-row (table-row contents info)
 			      (org-element-lineage table-row 'table) info))))
 	   (format "%s
 \\endfirsthead
-\\multicolumn{%d}{l}{%s} \\\\[0pt]
+\\multicolumn{%d}{l}{%s} \\\\
 %s
-%s \\\\[0pt]\n
+%s \\\\\n
 %s
 \\endhead
 %s\\multicolumn{%d}{r}{%s} \\\\
@@ -4211,15 +4196,15 @@ (defun org-latex-verse-block (verse-block contents info)
 	       (replace-regexp-in-string
                 (if (not lit)
 		    (rx-to-string
-                     `(seq (group ,org-latex-line-break-safe "\n")
-		           (1+ (group line-start (0+ space) ,org-latex-line-break-safe "\n"))))
-		  (concat "^[ \t]*" (regexp-quote org-latex-line-break-safe) "$"))
+                     `(seq (group "\\\\\n")
+		           (1+ (group line-start (0+ space) "\\\\\n"))))
+		  "^[ \t]*\\\\$")
 	        (if (not lit)
 		    (if lin "\\\\!\n\n" "\n\n")
 		  "\\vspace*{\\baselineskip}")
 	        (replace-regexp-in-string
 	         "\\([ \t]*\\\\\\\\\\)?[ \t]*\n"
-                 (concat org-latex-line-break-safe "\n")
+                 "\\\\\n"
 	         (if (not lit)
 		     (concat (org-trim contents t) "\n")
 		   contents)
diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el
index 92ccd2a05..6ee790894 100644
--- a/testing/lisp/test-org-table.el
+++ b/testing/lisp/test-org-table.el
@@ -1633,11 +1633,11 @@ (ert-deftest test-org-table/to-generic ()
 (ert-deftest test-org-table/to-latex ()
   "Test `orgtbl-to-latex' specifications."
   (should
-   (equal "\\begin{tabular}{l}\na\\\\[0pt]\n\\end{tabular}"
+   (equal "\\begin{tabular}{l}\na\\\\\n\\end{tabular}"
 	  (orgtbl-to-latex (org-table-to-lisp "| a |") nil)))
   ;; Test :environment parameter.
   (should
-   (equal "\\begin{tabularx}{l}\na\\\\[0pt]\n\\end{tabularx}"
+   (equal "\\begin{tabularx}{l}\na\\\\\n\\end{tabularx}"
 	  (orgtbl-to-latex (org-table-to-lisp "| a |")
 			   '(:environment "tabularx"))))
   ;; Test :booktabs parameter.
@@ -1646,7 +1646,7 @@ (ert-deftest test-org-table/to-latex ()
     "\\toprule" (orgtbl-to-latex (org-table-to-lisp "| a |") '(:booktabs t))))
   ;; Handle LaTeX snippets.
   (should
-   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\[0pt]\n\\end{tabular}"
+   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\n\\end{tabular}"
 	  (orgtbl-to-latex (org-table-to-lisp "| $x$ |") nil)))
   ;; Test pseudo objects and :raw parameter.
   (should
diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el
index 237ad97ec..d0be4e5a4 100644
--- a/testing/lisp/test-ox-latex.el
+++ b/testing/lisp/test-ox-latex.el
@@ -71,14 +71,14 @@ (ert-deftest test-ox-latex/verse ()
     (should
      (search-forward
       "\\begin{verse}
-lorem ipsum dolor\\\\[0pt]
+lorem ipsum dolor\\\\
 lorem ipsum dolor
 
-lorem ipsum dolor\\\\[0pt]
+lorem ipsum dolor\\\\
 lorem ipsum dolor
 
-lorem ipsum dolor\\\\[0pt]
-lorem ipsum dolor\\\\[0pt]
+lorem ipsum dolor\\\\
+lorem ipsum dolor\\\\
 \\end{verse}"))))
 
 (ert-deftest test-ox-latex/longtable ()
@@ -98,15 +98,15 @@ (ert-deftest test-ox-latex/longtable ()
     (should
      (search-forward
       "\\begin{longtable}{lr}
-First & Second\\\\[0pt]
-Column & Column\\\\[0pt]
+First & Second\\\\
+Column & Column\\\\
 \\hline
 \\endfirsthead"))
     (goto-char (point-min))
     (should
      (search-forward
-      "First & Second\\\\[0pt]
-Column & Column \\\\[0pt]
+      "First & Second\\\\
+Column & Column \\\\
 
 \\hline
 \\endhead"))
-- 
2.43.0


[-- Attachment #4: Type: text/plain, Size: 224 bytes --]


-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

^ permalink raw reply related	[relevance 35%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 18:47  9%                                 ` Ihor Radchenko
  2024-01-20 20:27 18%                                   ` Juan Manuel Macías
@ 2024-01-21  6:06 18%                                   ` Max Nikulin
  1 sibling, 0 replies; 200+ results
From: Max Nikulin @ 2024-01-21  6:06 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

On 21/01/2024 01:47, Ihor Radchenko wrote:
> Juan Manuel Macías writes:
>>
>> lorem\\ @@latex:[ipsum]@@ ==> the problem is in the user's territory

I agree with Juan Manuel.

> I see your point.
> Although I am still a bit hesitant to remove
> `org-latex-line-break-safe'.
> What would be the benefit of removing it? For now, I mostly just see
> that it will make the life harder for users in Scenario B.

An option might be disabling it by default without removing the code 
completely. Depending on user feedback it may be removed later.

Users, who need to submit LaTeX code, consider [0pt] as undesired noise. 
I see their point of view.


^ permalink raw reply	[relevance 18%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 12:41  9%                         ` Ihor Radchenko
@ 2024-01-21  5:56 20%                           ` Max Nikulin
  0 siblings, 0 replies; 200+ results
From: Max Nikulin @ 2024-01-21  5:56 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: emacs-orgmode

On 20/01/2024 19:41, Ihor Radchenko wrote:
> Max Nikulin writes:
> 
>> To have an additional excuse, it is better to add a note that it is
>> inspired by pandoc strategy.
> 
> I can add it to the code comment, but for different reason. We do not
> give "excuses" to make breaking changes - https://bzg.fr/en/the-software-maintainers-pledge/
> But we do keep the flexibility to make changes where Org mode behavior
> is undefined. Like in this case.

De-facto \\[0pt] was a breaking change despite formal contracts. I do 
not consider it as a wrong decision though. It is the case when where 
was no good choice, instead just ones that may cause some troubles 
(including leaving everything as is).

I recall some threads (besides ones started by Juan Manuel) where users 
considered [0pt] as an undesired consequence of some other changes. That 
is why I wrote "excuse".



^ permalink raw reply	[relevance 20%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 12:35 10%     ` Ihor Radchenko
@ 2024-01-21  5:44  9%       ` Max Nikulin
  2024-01-31 15:09  9%         ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2024-01-21  5:44 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: Juan Manuel Macías

On 20/01/2024 19:35, Ihor Radchenko wrote:
> Max Nikulin writes:
> 
>>>> Can anyone think of a possible scenario where removing the '\\[0pt]' in
>>>> the last line would cause a problem?
>>
>> I would suggest to strip leading and trailing newlines before processing
>> of the block content.
> 
> May you elaborate?

I expect that

#+BEGIN_VERSE


 From fairest creatures we desire increase,
That thereby beauty’s rose might never die,



#+END_VERSE

is exported to

\begin{verse}
 From fairest creatures we desire increase,\\
That thereby beauty’s rose might never die,
\end{verse}

and internally at some point it is represented as
"From fairest creatures we desire increase,\nThat thereby beauty’s rose 
might never die,"
without leading and trailing newlines.

>>> In such scenario, we may technically violate what users ask us to do:
>>>
>>> #+begin_verse
>>> I really want newline here\\
>>> #+end_verse
>>
>> I really want newline here@@latex:\\%@@
> 
> This implies that Org mode does not follow its own markup. I disagree
> with such suggestion.

I do not see any use case for "\\" at the last line. Perhaps it might 
even cause an org-lint warning. From my point of view, it is preferable 
to require more verbose markup in special cases to make intentions explicit.


^ permalink raw reply	[relevance 9%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 18:47  9%                                 ` Ihor Radchenko
@ 2024-01-20 20:27 18%                                   ` Juan Manuel Macías
  2024-01-21 13:42 35%                                     ` Ihor Radchenko
  2024-01-21  6:06 18%                                   ` Max Nikulin
  1 sibling, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-20 20:27 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode, Max Nikulin

Ihor Radchenko writes:

> I see your point.
> Although I am still a bit hesitant to remove
> `org-latex-line-break-safe'.
> What would be the benefit of removing it? For now, I mostly just see
> that it will make the life harder for users in Scenario B.

It's a complicated situation, because we now have two solutions to the
same problem... It certainly sounds a bit abrupt to remove
org-latex-line-break-safe (at least for now). I see no problem in both
solutions coexisting. After all, the user can always give an "\\\\"
value to org-latex-line-break-safe. The other possibility is that
org-latex-line-break-safe is selectively deleted, as you mentioned in a
previous email. In tables and verse blocks, unless I'm missing
something, I think adding [0pt] would be unnecessary, with the new
solution.

> For verse blocks, AFAIU, even \\ is problematic. (Correct me if I am wrong)

From the tests I have done, the problem of the vertical space being
altered after the verse environment only appears when the last line ends
in \\[0pt]. If it ends in \\ the problem does not appear. It is not
recommended that a verse environment ends in \\, but it does not seem to
influence the output. In fact, that was how it was in Org in the days
pre org-latex-line-break-safe and there were never any problems.

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 18%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 15:41  9%                               ` Juan Manuel Macías
@ 2024-01-20 18:47  9%                                 ` Ihor Radchenko
  2024-01-20 20:27 18%                                   ` Juan Manuel Macías
  2024-01-21  6:06 18%                                   ` Max Nikulin
  0 siblings, 2 replies; 200+ results
From: Ihor Radchenko @ 2024-01-20 18:47 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode, Max Nikulin

Juan Manuel Macías <maciaschain@posteo.net> writes:

> Scenario B:
>
> lorem\\ @@latex:[ipsum]@@ ==> the problem is in the user's territory

I see your point.
Although I am still a bit hesitant to remove
`org-latex-line-break-safe'.
What would be the benefit of removing it? For now, I mostly just see
that it will make the life harder for users in Scenario B.

For verse blocks, AFAIU, even \\ is problematic. (Correct me if I am wrong)

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 9%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 13:46  9%                             ` Ihor Radchenko
@ 2024-01-20 15:41  9%                               ` Juan Manuel Macías
  2024-01-20 18:47  9%                                 ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-20 15:41 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode, Max Nikulin

Ihor Radchenko writes:

> Juan Manuel Macías <maciaschain@posteo.net> writes:
>
>>> Paragraph\\
>>> @@latex:[foo]@@
>>
>> But since in both cases it is literal LaTeX code, the correct thing
>> would be for the user to be in charge of adding the curly braces to the
>> square brackets. I mean in such scenario it is LaTeX code, not Org.
>
> Not really. Because we do not give guarantees about the details of LaTeX
> export, we should try hard to not break things that users may put into
> literal export snippets.
>
>> Anyway, in both examples it does not make sense for LaTeX to end a
>> paragraph with the \\ macro, which is why we commented in previous
>> messages in the thread. The \\ macro is only used in horizontal mode;
>> this macro does not add a new paragraph but rather a forced line break
>> within the paragraph.
>
> In the example with @@latex:[foo]@@, \\ is not at the end of a paragraph
> - it is inside paragraph.

What I mean is that literal LaTeX code is LaTeX code, despite the
redundancy. IMHO, Org's only duty in that case is to export such literal
code as valid LaTeX code, but Org "does not know" what that literal code
consists of. The user who enters the literal LaTeX code is the one who
has the duty to add the necessary elements to that code so that it is
compiled correctly by LaTeX. Let's look at this as a territorial
question:

Scenario A:

@@LaTeX:\libebreak@@ [ipsum] ==> the problem is in Org territory

Scenario B:

lorem\\ @@latex:[ipsum]@@ ==> the problem is in the user's territory

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 9%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 13:22  9%                           ` Juan Manuel Macías
@ 2024-01-20 13:46  9%                             ` Ihor Radchenko
  2024-01-20 15:41  9%                               ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2024-01-20 13:46 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode, Max Nikulin

Juan Manuel Macías <maciaschain@posteo.net> writes:

>> Paragraph\\
>> @@latex:[foo]@@
>
> But since in both cases it is literal LaTeX code, the correct thing
> would be for the user to be in charge of adding the curly braces to the
> square brackets. I mean in such scenario it is LaTeX code, not Org.

Not really. Because we do not give guarantees about the details of LaTeX
export, we should try hard to not break things that users may put into
literal export snippets.

> Anyway, in both examples it does not make sense for LaTeX to end a
> paragraph with the \\ macro, which is why we commented in previous
> messages in the thread. The \\ macro is only used in horizontal mode;
> this macro does not add a new paragraph but rather a forced line break
> within the paragraph.

In the example with @@latex:[foo]@@, \\ is not at the end of a paragraph
- it is inside paragraph.

Another alternative could be modifying how inline latex snippet is
exported, but that's worse IMHO - we should try hard not to touch what
users tell Org to do explicitly.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 9%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 12:34 10%                         ` Ihor Radchenko
@ 2024-01-20 13:22  9%                           ` Juan Manuel Macías
  2024-01-20 13:46  9%                             ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-20 13:22 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode, Max Nikulin

Ihor Radchenko writes:

> Juan Manuel Macías <maciaschain@posteo.net> writes:
>
>>> \begin{itemize}
>>> \item {[}bax]
>>> \item {[}aur]
>>> \end{itemize}
>>
>> Great! Simple and effective. And more surgical than pandoc's global
>> solution. But now a question arises... Your code clearly solves the
>> problem that led to the declaration of org-latex-line-break-safe,
>> without foreseeing any unwanted effects, since it is the solution that
>> is usually recommended from LaTeX. So, if this code is included in Org,
>> what is the future of org-latex-line-break-safe?
>
> It is still useful in situations like
>
> Paragraph\\
>
> #+begin_export latex
> [foo]
> #+end_export
>
> or
>
> Paragraph\\
> @@latex:[foo]@@

But since in both cases it is literal LaTeX code, the correct thing
would be for the user to be in charge of adding the curly braces to the
square brackets. I mean in such scenario it is LaTeX code, not Org.

Anyway, in both examples it does not make sense for LaTeX to end a
paragraph with the \\ macro, which is why we commented in previous
messages in the thread. The \\ macro is only used in horizontal mode;
this macro does not add a new paragraph but rather a forced line break
within the paragraph.

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 9%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 10:09 18%                       ` Max Nikulin
  2024-01-20 10:57 10%                         ` Juan Manuel Macías
@ 2024-01-20 12:41  9%                         ` Ihor Radchenko
  2024-01-21  5:56 20%                           ` Max Nikulin
  1 sibling, 1 reply; 200+ results
From: Ihor Radchenko @ 2024-01-20 12:41 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

> It means that [0pt] is not necessary any more. However users will have 
> adjust their filters once more. I have no idea if many of them will 
> complain concerning {[} where it is not really required. (/[omitted]/).

We do not promise the exact way the exported LaTeX file looks like. User
filters are too flexible - we cannot reasonably guarantee that they will
keep working if they rely on the way Org mode transcodes to LaTeX in
specific Org version.

> To have an additional excuse, it is better to add a note that it is 
> inspired by pandoc strategy.

I can add it to the code comment, but for different reason. We do not
give "excuses" to make breaking changes - https://bzg.fr/en/the-software-maintainers-pledge/
But we do keep the flexibility to make changes where Org mode behavior
is undefined. Like in this case.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 9%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 10:27 10%   ` Max Nikulin
@ 2024-01-20 12:35 10%     ` Ihor Radchenko
  2024-01-21  5:44  9%       ` Max Nikulin
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2024-01-20 12:35 UTC (permalink / raw)
  To: Max Nikulin; +Cc: Juan Manuel Macías, orgmode

Max Nikulin <manikulin@gmail.com> writes:

>>> Can anyone think of a possible scenario where removing the '\\[0pt]' in
>>> the last line would cause a problem?
>
> I would suggest to strip leading and trailing newlines before processing 
> of the block content.

May you elaborate?

>> In such scenario, we may technically violate what users ask us to do:
>> 
>> #+begin_verse
>> I really want newline here\\
>> #+end_verse
>
> I really want newline here@@latex:\\%@@

This implies that Org mode does not follow its own markup. I disagree
with such suggestion.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 10%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-19 17:28 10%                       ` Juan Manuel Macías
@ 2024-01-20 12:34 10%                         ` Ihor Radchenko
  2024-01-20 13:22  9%                           ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2024-01-20 12:34 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode, Max Nikulin

Juan Manuel Macías <maciaschain@posteo.net> writes:

>> \begin{itemize}
>> \item {[}bax]
>> \item {[}aur]
>> \end{itemize}
>
> Great! Simple and effective. And more surgical than pandoc's global
> solution. But now a question arises... Your code clearly solves the
> problem that led to the declaration of org-latex-line-break-safe,
> without foreseeing any unwanted effects, since it is the solution that
> is usually recommended from LaTeX. So, if this code is included in Org,
> what is the future of org-latex-line-break-safe?

It is still useful in situations like

Paragraph\\
#+begin_export latex
[foo]
#+end_export

or

Paragraph\\
@@latex:[foo]@@

My patch does not do anything about verbatim environments.

We may remove the use of `org-latex-line-break-safe' from some places,
but not all.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 10%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-13 15:08 10% ` Ihor Radchenko
  2024-01-13 16:05 18%   ` Juan Manuel Macías
@ 2024-01-20 10:27 10%   ` Max Nikulin
  2024-01-20 12:35 10%     ` Ihor Radchenko
  1 sibling, 1 reply; 200+ results
From: Max Nikulin @ 2024-01-20 10:27 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

On 13/01/2024 22:08, Ihor Radchenko wrote:
> Juan Manuel Macías writes:
> 
>> Can anyone think of a possible scenario where removing the '\\[0pt]' in
>> the last line would cause a problem?

I would suggest to strip leading and trailing newlines before processing 
of the block content.

> In such scenario, we may technically violate what users ask us to do:
> 
> #+begin_verse
> I really want newline here\\
> #+end_verse

I really want newline here@@latex:\\%@@

P.S. Juan Manuel, I have sent another message to this thread without 
your address in Cc.


^ permalink raw reply	[relevance 10%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-20 10:09 18%                       ` Max Nikulin
@ 2024-01-20 10:57 10%                         ` Juan Manuel Macías
  2024-01-20 12:41  9%                         ` Ihor Radchenko
  1 sibling, 0 replies; 200+ results
From: Juan Manuel Macías @ 2024-01-20 10:57 UTC (permalink / raw)
  To: Max Nikulin; +Cc: Ihor Radchenko, orgmode

Max Nikulin writes:

> On 18/01/2024 20:05, Ihor Radchenko wrote:
>> With the patch, I am getting the following:[...]
>> \begin{center}
>> \begin{tabular}{lr}
>> {[}foo] & 2\\[0pt]
>> {[}bar] & 3\\[0pt]
>> \end{tabular}
>> \end{center}
>
> It means that [0pt] is not necessary any more. However users will have
> adjust their filters once more. I have no idea if many of them will
> complain concerning {[} where it is not really required.
> (/[omitted]/).
>
> To have an additional excuse, it is better to add a note that it is
> inspired by pandoc strategy.

I agree with the note. Perhaps both strategies could coexist: by
default, Ihor's code; and org-latex-line-break-safe with value "\\\\".
And, after some time, the latter could become obsolete, unless a new
''raison d'etre'' is found for it...

In any case, I would no longer see it necessary to modify
org-latex-verse-block anymore.

Best regards,

Juan Manuel 



^ permalink raw reply	[relevance 10%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-18 13:05 15%                     ` Ihor Radchenko
  2024-01-19 17:28 10%                       ` Juan Manuel Macías
@ 2024-01-20 10:09 18%                       ` Max Nikulin
  2024-01-20 10:57 10%                         ` Juan Manuel Macías
  2024-01-20 12:41  9%                         ` Ihor Radchenko
  1 sibling, 2 replies; 200+ results
From: Max Nikulin @ 2024-01-20 10:09 UTC (permalink / raw)
  To: emacs-orgmode

On 18/01/2024 20:05, Ihor Radchenko wrote:
> With the patch, I am getting the following:[...]
> \begin{center}
> \begin{tabular}{lr}
> {[}foo] & 2\\[0pt]
> {[}bar] & 3\\[0pt]
> \end{tabular}
> \end{center}

It means that [0pt] is not necessary any more. However users will have 
adjust their filters once more. I have no idea if many of them will 
complain concerning {[} where it is not really required. (/[omitted]/).

To have an additional excuse, it is better to add a note that it is 
inspired by pandoc strategy.



^ permalink raw reply	[relevance 18%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-18 13:05 15%                     ` Ihor Radchenko
@ 2024-01-19 17:28 10%                       ` Juan Manuel Macías
  2024-01-20 12:34 10%                         ` Ihor Radchenko
  2024-01-20 10:09 18%                       ` Max Nikulin
  1 sibling, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-19 17:28 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode, Max Nikulin

Ihor Radchenko writes:

> This turned out to be a lot easier than I thought.
> See the attached patch.
>
>>> \command
>>> [unrelated text]
>>>
>>> If there are, we may actually want to consider pandoc's approach
>>> seriously.
>>
>> In principle, any environment that takes an optional argument in a
>> "dangerous" position. Just do a simple test. Something like this:
>>
>> #+begin_figure
>> [lorem] ipsum
>> #+end_figure
>>
>> will throw an error like ''LaTeX Error: Unknown float option...''
>>
>> Of course, putting an empty line after #+begin... usually solves it. But
>> the user may not know it.
>>
>> There are also a number of commands with an optional argument. For
>> example \pagebreak. Something like this will give an error:
>>
>> lorem @@latex:\pagebreak@@ [ipsum]
>>
>> \item is another typical example, but in this case org adds \relax.
>
> With the patch, I am getting the following:
>
> * This is test
> lorem @@latex:\pagebreak@@ [ipsum]
>
> #+begin_figure
> [lorem] figure
> #+end_figure
>
> | [foo] | 2 |
> | [bar] | 3 |
>
> - [bax]
> - [aur]
>
> exports to
>
> lorem \pagebreak {[}ipsum]
>
> \begin{figure}
> {[}lorem] figure
> \end{figure}
>
> \begin{center}
> \begin{tabular}{lr}
> {[}foo] & 2\\[0pt]
> {[}bar] & 3\\[0pt]
> \end{tabular}
> \end{center}
>
> \begin{itemize}
> \item {[}bax]
> \item {[}aur]
> \end{itemize}

Great! Simple and effective. And more surgical than pandoc's global
solution. But now a question arises... Your code clearly solves the
problem that led to the declaration of org-latex-line-break-safe,
without foreseeing any unwanted effects, since it is the solution that
is usually recommended from LaTeX. So, if this code is included in Org,
what is the future of org-latex-line-break-safe?

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 10%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-17 17:50 13%                   ` Juan Manuel Macías
@ 2024-01-18 13:05 15%                     ` Ihor Radchenko
  2024-01-19 17:28 10%                       ` Juan Manuel Macías
  2024-01-20 10:09 18%                       ` Max Nikulin
  0 siblings, 2 replies; 200+ results
From: Ihor Radchenko @ 2024-01-18 13:05 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode, Max Nikulin

[-- Attachment #1: Type: text/plain, Size: 1866 bytes --]

Juan Manuel Macías <maciaschain@posteo.net> writes:

>> As for {[}{]}, it is a bit difficult to implement. Especially when we
>> also consider user filters and derived backends. If we have several
>> transcoders of consequent elements, there is always a risk that even
>> when a given filter/transcoder is generating a valid LaTeX code,
>> concatenating them may still cause issues like we have with \\.
>
> I see. I think pandoc's solution is what Leslie Lamport recommends
> (naturally, Lamport doesn't say to enclose /all/ brackets in curly
> braces).

This turned out to be a lot easier than I thought.
See the attached patch.

>> \command
>> [unrelated text]
>>
>> If there are, we may actually want to consider pandoc's approach
>> seriously.
>
> In principle, any environment that takes an optional argument in a
> "dangerous" position. Just do a simple test. Something like this:
>
> #+begin_figure
> [lorem] ipsum
> #+end_figure
>
> will throw an error like ''LaTeX Error: Unknown float option...''
>
> Of course, putting an empty line after #+begin... usually solves it. But
> the user may not know it.
>
> There are also a number of commands with an optional argument. For
> example \pagebreak. Something like this will give an error:
>
> lorem @@latex:\pagebreak@@ [ipsum]
>
> \item is another typical example, but in this case org adds \relax.

With the patch, I am getting the following:

* This is test
lorem @@latex:\pagebreak@@ [ipsum]

#+begin_figure
[lorem] figure
#+end_figure

| [foo] | 2 |
| [bar] | 3 |

- [bax]
- [aur]

exports to

lorem \pagebreak {[}ipsum]

\begin{figure}
{[}lorem] figure
\end{figure}

\begin{center}
\begin{tabular}{lr}
{[}foo] & 2\\[0pt]
{[}bar] & 3\\[0pt]
\end{tabular}
\end{center}

\begin{itemize}
\item {[}bax]
\item {[}aur]
\end{itemize}


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Make-sure-that-text-is-not-misinterpreted-a.patch --]
[-- Type: text/x-patch, Size: 2511 bytes --]

From db3fa01d6f15b3d3f499f77e342a608a822029c8 Mon Sep 17 00:00:00 2001
Message-ID: <db3fa01d6f15b3d3f499f77e342a608a822029c8.1705583005.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Thu, 18 Jan 2024 14:01:32 +0100
Subject: [PATCH] ox-latex: Make sure that [text] is not misinterpreted as
 LaTeX argument

* lisp/ox-latex.el (org-latex-plain-text): Protect plain text starting
from [.  It might be misinterpreted as optional command argument if
previous exported fragment ends with a command accepting such.
*
testing/lisp/test-ox-latex.el (text-ox-latex/protect-square-brackets):
Add new test.

Link: https://orgmode.org/list/87o7dju9vn.fsf@posteo.net
---
 lisp/ox-latex.el              |  9 +++++++++
 testing/lisp/test-ox-latex.el | 23 +++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 432f09f4e..a3505c25f 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3094,6 +3094,15 @@ (defun org-latex-plain-text (text info)
 		    "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n"
                     (concat org-latex-line-break-safe "\n")
                     output nil t)))
+    ;; Protect [foo] at the beginning of lines / beginning of the
+    ;; plain-text object.  This prevents LaTeX from unexpectedly
+    ;; interpreting @@latex:\pagebreak@@ [foo] as a command with
+    ;; optional argument.
+    (setq output (replace-regexp-in-string
+                  (rx bol (0+ space) (group "["))
+                  "{[}"
+                  output
+                  nil nil 1))
     ;; Return value.
     output))
 
diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el
index 41df1b823..237ad97ec 100644
--- a/testing/lisp/test-ox-latex.el
+++ b/testing/lisp/test-ox-latex.el
@@ -29,6 +29,29 @@ (unless (featurep 'ox-latex)
 
 \f
 
+(ert-deftest text-ox-latex/protect-square-brackets ()
+  "Test [foo] being interpreted as plain text even after LaTeX commands."
+  (org-test-with-exported-text
+      'latex
+      "* This is test
+lorem @@latex:\\pagebreak@@ [ipsum]
+
+#+begin_figure
+[lorem] figure
+#+end_figure
+
+| [foo] | 2 |
+| [bar] | 3 |
+
+- [bax]
+- [aur]
+"
+    (goto-char (point-min))
+    (should (search-forward "lorem \\pagebreak {[}ipsum]"))
+    (should (search-forward "{[}lorem] figure"))
+    (should (search-forward "{[}foo]"))
+    (should (search-forward "\\item {[}bax]"))))
+
 (ert-deftest test-ox-latex/verse ()
   "Test verse blocks."
   (org-test-with-exported-text
-- 
2.43.0


[-- Attachment #3: Type: text/plain, Size: 224 bytes --]


-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

^ permalink raw reply related	[relevance 15%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-17 13:00 17%                 ` Ihor Radchenko
  2024-01-17 15:58  9%                   ` Max Nikulin
@ 2024-01-17 17:50 13%                   ` Juan Manuel Macías
  2024-01-18 13:05 15%                     ` Ihor Radchenko
  1 sibling, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-17 17:50 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode, Max Nikulin

Ihor Radchenko writes:


> If the idea with custom command does not have obvious downsides, it
> might be a better option. In the previous thread, we only considered
> redefining \\ itself - obviously a non-starter for environments that
> re-define \\ by their own, like here.

I find several drawbacks to adding a new latex command like \nothing.
First, the standardization of the exported LaTeX code is lost. \\[0pt],
at least, always compiles. A new command obviously needs to be defined
first. Let's imagine that someone wants to simply share the LaTeX code
of a table... Then there is the problem of how to name the new command
so that it doesn't 'clash' with some user-defined command. In LaTeX it
is usually good practice to use the at sign character (@) in the name of
a command or macro that is not in user space, since this character can
only be used in a *.sty file. In a *.tex file, if you want to use the at
sign to define or redefine something, you have to enclose the code
between \makeatletter...\makeatother. And, in any case, I think that the
LaTeX code produced by org should be as 'universal' as possible (standard
LaTeX code + packages included in TeX live), and leave the definition of
new commands or environments to the user's discretion.

On the other hand, we are not sure that a command like \nothing does not
have some undesirable effect. I seem to remember that in the
aforementioned thread, adding \relax (the typical command that is used
to tell LaTeX do nothing) was also proposed as a solution, and it was
discarded for some reason.

>> In any case, square brackets are a problematic character in LaTeX
>> (think, e.g., of some environment that takes an optional argument). I
>> think pandoc chooses to always export them as {[}{]}:
>>
>> #+begin_src sh :results latex
>> str="[hello world] [foo] [bar]"
>> pandoc -f org -t latex <<< $str
>> #+end_src
>>
>> #+RESULTS:
>> #+begin_export latex
>> {[}hello world{]} {[}foo{]} {[}bar{]}
>> #+end_export
>>
>> We could do the same, but I'm afraid it's too late if
>> org-latex-line-break-safe already exists... I don't remember if
>> something similar was proposed in that discussion, and it was rejected
>> for some reason.
>
> It is not too late.
>
> AFAIR, we just decided not to dig deeper about pandoc's approach.
>
> As for {[}{]}, it is a bit difficult to implement. Especially when we
> also consider user filters and derived backends. If we have several
> transcoders of consequent elements, there is always a risk that even
> when a given filter/transcoder is generating a valid LaTeX code,
> concatenating them may still cause issues like we have with \\.

I see. I think pandoc's solution is what Leslie Lamport recommends
(naturally, Lamport doesn't say to enclose /all/ brackets in curly
braces).

> I am wondering if there are other examples of commands with optional
> arguments that may cause a similar problem with
>
> \command
> [unrelated text]
>
> If there are, we may actually want to consider pandoc's approach
> seriously.

In principle, any environment that takes an optional argument in a
"dangerous" position. Just do a simple test. Something like this:

#+begin_figure
[lorem] ipsum
#+end_figure

will throw an error like ''LaTeX Error: Unknown float option...''

Of course, putting an empty line after #+begin... usually solves it. But
the user may not know it.

There are also a number of commands with an optional argument. For
example \pagebreak. Something like this will give an error:

lorem @@latex:\pagebreak@@ [ipsum]

\item is another typical example, but in this case org adds \relax.

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 13%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-17 13:00 17%                 ` Ihor Radchenko
@ 2024-01-17 15:58  9%                   ` Max Nikulin
  2024-01-17 17:50 13%                   ` Juan Manuel Macías
  1 sibling, 0 replies; 200+ results
From: Max Nikulin @ 2024-01-17 15:58 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

On 17/01/2024 20:00, Ihor Radchenko wrote:
>>> \newcommand\nothing{}
>>> \newcommand{\safenewline}{\\\nothing}
[...]
>>> \begin{center}
>>> \begin{tabular}{ll}
>>> [t] & s\safenewline
[...]
> If the idea with custom command does not have obvious downsides

It does for tabularray https://github.com/lvjr/tabularray/issues/328
due to a custom parser, but probably it is safe for verse.

I think, it is necessary to wait a couple of years till the fix will 
propagate to all stable Linux distributions.

Notice that an arbitrary custom command is not the same as \empty. 
\safenewline would require more tricks, even \nothing would need

\NewTableCommand\nothing{}
Max Nikulin. Re: Line breaks and brackets in LaTeX export.
Fri, 21 Oct 2022 23:38:29 +0700.
https://list.orgmode.org/tiuhu5$nlp$2@ciao.gmane.io

or

\begin{tblr}[expand=\nothing]{rl}
Max Nikulin. Re: Line breaks and brackets in LaTeX export.
Thu, 20 Oct 2022 00:07:54 +0700.
https://list.orgmode.org/65a1c205-cd18-4abe-b36d-a93763d7f5e8@gmail.com

As to verse, I believe, \\... should be added at the end, but if a user 
added it explicitly then it should not be stripped.


^ permalink raw reply	[relevance 9%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-16 19:33 18%               ` Juan Manuel Macías
@ 2024-01-17 13:00 17%                 ` Ihor Radchenko
  2024-01-17 15:58  9%                   ` Max Nikulin
  2024-01-17 17:50 13%                   ` Juan Manuel Macías
  0 siblings, 2 replies; 200+ results
From: Ihor Radchenko @ 2024-01-17 13:00 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode, Max Nikulin

Juan Manuel Macías <maciaschain@posteo.net> writes:

>> May it be better to use something like
>>
>> \newcommand\nothing{}
>> \newcommand{\safenewline}{\\\nothing}
>>
>> And then use \safenewline instead of \\[0pt]
>>
>> In my tests,
>>
>> \begin{center}
>> \begin{tabular}{ll}
>> [t] & s\safenewline
>> [I] & A\safenewline
>> [m] & kg\safenewline
>> \end{tabular}
>> \end{center}
>>
>> Does not suffer from misinterpreting new line as argument.
>
> I remember the thread where these issues were discussed and the long
> discussion where many alternatives were proposed. After all, the \\[0pt]
> solution still seems the safest to me. It seems that the problem is
> located only in the verse environment, probably due to some particular
> redefinition of the \\ macro that makes that environment.

We chose \\[0pt] simply because we did not find anything better.
In fact, Max expressed some concerns about \\[0pt] - in
https://list.orgmode.org/orgmode/tik0uf$td1$1@ciao.gmane.io/ and
https://list.orgmode.org/orgmode/tio0th$vn8$1@ciao.gmane.io/

If the idea with custom command does not have obvious downsides, it
might be a better option. In the previous thread, we only considered
redefining \\ itself - obviously a non-starter for environments that
re-define \\ by their own, like here.

> In any case, square brackets are a problematic character in LaTeX
> (think, e.g., of some environment that takes an optional argument). I
> think pandoc chooses to always export them as {[}{]}:
>
> #+begin_src sh :results latex
> str="[hello world] [foo] [bar]"
> pandoc -f org -t latex <<< $str
> #+end_src
>
> #+RESULTS:
> #+begin_export latex
> {[}hello world{]} {[}foo{]} {[}bar{]}
> #+end_export
>
> We could do the same, but I'm afraid it's too late if
> org-latex-line-break-safe already exists... I don't remember if
> something similar was proposed in that discussion, and it was rejected
> for some reason.

It is not too late.

AFAIR, we just decided not to dig deeper about pandoc's approach.

As for {[}{]}, it is a bit difficult to implement. Especially when we
also consider user filters and derived backends. If we have several
transcoders of consequent elements, there is always a risk that even
when a given filter/transcoder is generating a valid LaTeX code,
concatenating them may still cause issues like we have with \\.

I am wondering if there are other examples of commands with optional
arguments that may cause a similar problem with

\command
[unrelated text]

If there are, we may actually want to consider pandoc's approach
seriously.

>> We may as well strip the trailing \\[0pt] there.
>
> I think it would be best to remove the last \\[0pt] in the verse block.
> I can prepare a patch, but I'm afraid that org-latex-verse-block is
> becoming an homage to replace-regexp-in-string...

Not a big deal. Or, if you want, you can make changes via temporary
buffer; if that is cleaner.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 17%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-16 14:09 18%             ` Ihor Radchenko
@ 2024-01-16 19:33 18%               ` Juan Manuel Macías
  2024-01-17 13:00 17%                 ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-16 19:33 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode

Ihor Radchenko writes:

> The very reason we use \\[0pt] is because it supposed to prevent
> interpreting [...] at the new line/transcoded element as argument.
>
> You demonstrated that it is yet not always safe enough.
>
> May it be better to use something like
>
> \newcommand\nothing{}
> \newcommand{\safenewline}{\\\nothing}
>
> And then use \safenewline instead of \\[0pt]
>
> In my tests,
>
> \begin{center}
> \begin{tabular}{ll}
> [t] & s\safenewline
> [I] & A\safenewline
> [m] & kg\safenewline
> \end{tabular}
> \end{center}
>
> Does not suffer from misinterpreting new line as argument.

I remember the thread where these issues were discussed and the long
discussion where many alternatives were proposed. After all, the \\[0pt]
solution still seems the safest to me. It seems that the problem is
located only in the verse environment, probably due to some particular
redefinition of the \\ macro that makes that environment.

In any case, square brackets are a problematic character in LaTeX
(think, e.g., of some environment that takes an optional argument). I
think pandoc chooses to always export them as {[}{]}:

#+begin_src sh :results latex
str="[hello world] [foo] [bar]"
pandoc -f org -t latex <<< $str
#+end_src

#+RESULTS:
#+begin_export latex
{[}hello world{]} {[}foo{]} {[}bar{]}
#+end_export

We could do the same, but I'm afraid it's too late if
org-latex-line-break-safe already exists... I don't remember if
something similar was proposed in that discussion, and it was rejected
for some reason.

> `org-latex-verse-block' already has a giant regexp replacement:
>
>       ;; In a verse environment, add a line break to each newline
>       ;; character and change each white space at beginning of a line
>       ;; into a normal space, calculated with `\fontdimen2\font'.  One
>       ;; or more blank lines between lines are exported as a single
>       ;; blank line.  If the `:lines' attribute is used, the last
>       ;; verse of each stanza ends with the string `\\!', according to
>       ;; the syntax of the `verse' package. The separation between
>       ;; stanzas can be controlled with the length `\stanzaskip', of
>       ;; the aforementioned package.  If the `:literal' attribute is
>       ;; used, all blank lines are preserved and exported as
>       ;; `\vspace*{\baselineskip}', including the blank lines before
>       ;; or after CONTENTS.
>
> We may as well strip the trailing \\[0pt] there.

I think it would be best to remove the last \\[0pt] in the verse block.
I can prepare a patch, but I'm afraid that org-latex-verse-block is
becoming an homage to replace-regexp-in-string...

Best regards,

Juan Manuel 




^ permalink raw reply	[relevance 18%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-14 21:58 18%           ` Juan Manuel Macías
@ 2024-01-16 14:09 18%             ` Ihor Radchenko
  2024-01-16 19:33 18%               ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2024-01-16 14:09 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

Juan Manuel Macías <maciaschain@posteo.net> writes:

>>> If I'm not mistaken, in TeX '\\' can only be used in horizontal mode:
>>> that is, within a paragraph. At the end of an environment like verse
>>> (\end{verse}) you are forced to enter vertical mode, and a new paragraph
>>> starts.
>>
>> Is it true for any environment? Or just some?
>
> In principle, nothing prevents one from defining an environment for use
> in horizontal mode (within the paragraph). E.g.:
> ...
> But the usual thing is that the beginning/end of an environment changes to
> vertical mode, with \par or something more elaborate.

This is annoying.
ox-latex has some transcoders that unconditionally add \\ at the
end: clocks and planning lines. If they happen to be at the end of an
environment, it can be problematic.

> hmm... I don't know if this should be considered a bug. We may think
> that \\[0pt] should never do anything, but we must keep in mind that the
> end of the verse environment is the end of a paragraph, and it changes
> to vertical mode. And the end of a paragraph is an illogical place to
> put that command. But it seems that it also alters things when it is at
> that point. Check out this reply from David Carlisle
> (https://tex.stackexchange.com/a/82666):

The very reason we use \\[0pt] is because it supposed to prevent
interpreting [...] at the new line/transcoded element as argument.

You demonstrated that it is yet not always safe enough.

May it be better to use something like

\newcommand\nothing{}
\newcommand{\safenewline}{\\\nothing}

And then use \safenewline instead of \\[0pt]

In my tests,

\begin{center}
\begin{tabular}{ll}
[t] & s\safenewline
[I] & A\safenewline
[m] & kg\safenewline
\end{tabular}
\end{center}

Does not suffer from misinterpreting new line as argument.

> If there are environments that redefine \\, such as verse or tabular,
> probably putting the optional argument of \\ with a value of 0pt at the
> end of verse alters the calculation of the normal space after the
> environment, making it shorter. I think that here we would not have a
> LaTeX bug, because the syntax of the verse environment itself says that
> the last line should not carry any \\ mark. 

AFAIU, \safenewline should still use re-defined version of \\ according
to the context.

> At the end of the tables I have not noticed any side effects. But in the
> export of the verse block, I would be in favor of somehow eliminating
> that last \\[0pt].

`org-latex-verse-block' already has a giant regexp replacement:

      ;; In a verse environment, add a line break to each newline
      ;; character and change each white space at beginning of a line
      ;; into a normal space, calculated with `\fontdimen2\font'.  One
      ;; or more blank lines between lines are exported as a single
      ;; blank line.  If the `:lines' attribute is used, the last
      ;; verse of each stanza ends with the string `\\!', according to
      ;; the syntax of the `verse' package. The separation between
      ;; stanzas can be controlled with the length `\stanzaskip', of
      ;; the aforementioned package.  If the `:literal' attribute is
      ;; used, all blank lines are preserved and exported as
      ;; `\vspace*{\baselineskip}', including the blank lines before
      ;; or after CONTENTS.

We may as well strip the trailing \\[0pt] there.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 18%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-14 12:33 10%         ` Ihor Radchenko
@ 2024-01-14 21:58 18%           ` Juan Manuel Macías
  2024-01-16 14:09 18%             ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-14 21:58 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode

Ihor Radchenko writes:

> Juan Manuel Macías <maciaschain@posteo.net> writes:
>
>> If I'm not mistaken, in TeX '\\' can only be used in horizontal mode:
>> that is, within a paragraph. At the end of an environment like verse
>> (\end{verse}) you are forced to enter vertical mode, and a new paragraph
>> starts.
>
> Is it true for any environment? Or just some?

In principle, nothing prevents one from defining an environment for use
in horizontal mode (within the paragraph). E.g.:

\newenvironment{foo}{\itshape}{}

Lorem \begin{foo}ipsum\end{foo} dolor.

But the usual thing is that the beginning/end of an environment changes to
vertical mode, with \par or something more elaborate.


>> Therefore, I think that whether or not a verse environment ends with \\ is
>> irrelevant to LaTeX. The problem is that when it ends with \\[0pt], for
>> some reason that escapes me, the space after the environment is altered.
>
> I see. Although, I am not 100% if it is something we have to deal with
> in Org mode. May it be better to report this as a bug to LaTeX devs?

hmm... I don't know if this should be considered a bug. We may think
that \\[0pt] should never do anything, but we must keep in mind that the
end of the verse environment is the end of a paragraph, and it changes
to vertical mode. And the end of a paragraph is an illogical place to
put that command. But it seems that it also alters things when it is at
that point. Check out this reply from David Carlisle
(https://tex.stackexchange.com/a/82666):

#+begin_quote
\\ at the end of a paragraph causes bad output with an empty, maximally under-full, box,
and so you get a warning about badness 10000, the visual effect looks a bit like extra
vertical space but it is not: it is an extra spurious line at the end of the paragraph,
and for example it is not dropped at a page break and will break widow/club line
calculations.
#+end_quote

If there are environments that redefine \\, such as verse or tabular,
probably putting the optional argument of \\ with a value of 0pt at the
end of verse alters the calculation of the normal space after the
environment, making it shorter. I think that here we would not have a
LaTeX bug, because the syntax of the verse environment itself says that
the last line should not carry any \\ mark. 

At the end of the tables I have not noticed any side effects. But in the
export of the verse block, I would be in favor of somehow eliminating
that last \\[0pt].

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 18%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-13 20:22 18%       ` Juan Manuel Macías
@ 2024-01-14 12:33 10%         ` Ihor Radchenko
  2024-01-14 21:58 18%           ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2024-01-14 12:33 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

Juan Manuel Macías <maciaschain@posteo.net> writes:

> If I'm not mistaken, in TeX '\\' can only be used in horizontal mode:
> that is, within a paragraph. At the end of an environment like verse
> (\end{verse}) you are forced to enter vertical mode, and a new paragraph
> starts.

Is it true for any environment? Or just some?

> Therefore, I think that whether or not a verse environment ends with \\ is
> irrelevant to LaTeX. The problem is that when it ends with \\[0pt], for
> some reason that escapes me, the space after the environment is altered.

I see. Although, I am not 100% if it is something we have to deal with
in Org mode. May it be better to report this as a bug to LaTeX devs?

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 10%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-13 18:28 20%     ` Ihor Radchenko
@ 2024-01-13 20:22 18%       ` Juan Manuel Macías
  2024-01-14 12:33 10%         ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-13 20:22 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode

Ihor Radchenko writes:

> Juan Manuel Macías <maciaschain@posteo.net> writes:
>
>>> In such scenario, we may technically violate what users ask us to do:
>>>
>>> #+begin_verse
>>> I really want newline here\\
>>> #+end_verse
>>
>> I'm not sure if users asked for that specifically.
>> ...
>> This does not:
>>
>>  #+begin_verse
>>  I really want newline here\\
>>  #+end_verse
>
> I am not sure.
> What about
>
> #+begin_verse
> I really want newline here\\
> #+end_verse
>
> This must not be indented.

If I'm not mistaken, in TeX '\\' can only be used in horizontal mode:
that is, within a paragraph. At the end of an environment like verse
(\end{verse}) you are forced to enter vertical mode, and a new paragraph
starts. Doing something like this, for example, adds a new paragraph
after the environment:

\documentclass{article}
\usepackage{lipsum}
\begin{document}
\begin{verse}
  Lorem ipsum dolor\\
\end{verse}
\lipsum[1]
\end{document}

Even this one produces the same result:

\documentclass{article}
\usepackage{lipsum}
\begin{document}
\begin{verse}
  Lorem ipsum dolor\\
\end{verse}\lipsum[1]
\end{document}

If one wants, for example, that after a verse environment there is no
vertical space or indentation, the only way to do it is by modifying, globally or
locally (with another environment) the space after the environment and
adding a \noindent to the following paragraph:

\documentclass{article}
\usepackage{lipsum}
\setlength\partopsep{-\topsep}\addtolength\partopsep{0pt}
\begin{document}
\begin{verse}
  Lorem ipsum dolor\\
\end{verse}
\noindent\lipsum[1]
\end{document}

(taking into account that within the verse environment there is also a
left indentation that would also have to be modified).

Therefore, I think that whether or not a verse environment ends with \\ is
irrelevant to LaTeX. The problem is that when it ends with \\[0pt], for
some reason that escapes me, the space after the environment is altered.

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 18%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-13 16:05 18%   ` Juan Manuel Macías
@ 2024-01-13 18:28 20%     ` Ihor Radchenko
  2024-01-13 20:22 18%       ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2024-01-13 18:28 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

Juan Manuel Macías <maciaschain@posteo.net> writes:

>> In such scenario, we may technically violate what users ask us to do:
>>
>> #+begin_verse
>> I really want newline here\\
>> #+end_verse
>
> I'm not sure if users asked for that specifically.
> ...
> This does not:
>
>  #+begin_verse
>  I really want newline here\\
>  #+end_verse

I am not sure.
What about

#+begin_verse
I really want newline here\\
#+end_verse
This must not be indented.

(Just trying to come up with valid uses of newline at the end of
LaTeX environment)

Although, the above causes Org export to fail...
\begin{verse}
This is test\\[0pt]\\[0pt]
\end{verse}
Paragraph.


-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 20%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-13 15:08 10% ` Ihor Radchenko
@ 2024-01-13 16:05 18%   ` Juan Manuel Macías
  2024-01-13 18:28 20%     ` Ihor Radchenko
  2024-01-20 10:27 10%   ` Max Nikulin
  1 sibling, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-13 16:05 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode

Ihor Radchenko writes:

>> Can anyone think of a possible scenario where removing the '\\[0pt]' in
>> the last line would cause a problem? If not, I might send a patch in the
>> next few days. (I'm afraid that going back to abusing
>> replace-regexp-in-string. I can't think of any other more elegant
>> solution...).
>
> In such scenario, we may technically violate what users ask us to do:
>
> #+begin_verse
> I really want newline here\\
> #+end_verse

I'm not sure if users asked for that specifically.

You want a new line when there is a new line.

This makes sense:

 #+begin_verse
 I really want newline here\\
 blah...
 #+end_verse

This does not:

 #+begin_verse
 I really want newline here\\
 #+end_verse

For LaTeX it is the same as this:

 #+begin_verse
 I really want newline here
 #+end_verse

But this specifically alters the expected result in LaTeX, modifying the
space after the environment:

 #+begin_verse
 I really want newline here\\[0pt]
 #+end_verse

What is the cause? I don't know. But it happens.

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 18%]

* Re: [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
  2024-01-02 23:46 20% [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export Juan Manuel Macías
@ 2024-01-13 15:08 10% ` Ihor Radchenko
  2024-01-13 16:05 18%   ` Juan Manuel Macías
  2024-01-20 10:27 10%   ` Max Nikulin
  0 siblings, 2 replies; 200+ results
From: Ihor Radchenko @ 2024-01-13 15:08 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

Juan Manuel Macías <maciaschain@posteo.net> writes:

> Can anyone think of a possible scenario where removing the '\\[0pt]' in
> the last line would cause a problem? If not, I might send a patch in the
> next few days. (I'm afraid that going back to abusing
> replace-regexp-in-string. I can't think of any other more elegant
> solution...).

In such scenario, we may technically violate what users ask us to do:

#+begin_verse
I really want newline here\\
#+end_verse

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 10%]

* Re: org table export to latex, longtable, code does not compile
  @ 2024-01-03 15:56 11%   ` Uwe Brauer
  0 siblings, 0 replies; 200+ results
From: Uwe Brauer @ 2024-01-03 15:56 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Uwe Brauer, emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 2066 bytes --]

>>> "IR" == Ihor Radchenko <yantar92@posteo.net> writes:

> Uwe Brauer <oub@mat.ucm.es> writes:
>> I am running emacs 29 and org mode 9.6.9
>> 
>> I have set (setq org-latex-line-break-safe "\\\\")
>> ...
>> Will be translated to 
>> 
>> #+begin_src 
>> 
>> \begin{longtable}{|r|r|l|l|l|l|l|}
>> \hline
>> Num & Documento & \textit{26.04.2024} & \textit{29.04.2024} & \textit{06.05.2024} & \textit{08.05.2024} & \textit{10.05.2024}\\ \hline

> This is not what I am seeing with Emacs 29.

Very strange I have not set 
org-export-filter-table-row-functions to nil

But still the above example gets exported as 

\begin{longtable}{|r|r|l|l|l|l|l|}
\hline
Num & Documento & \textit{26.04.2024} & \textit{29.04.2024} & \textit{06.05.2024} & \textit{08.05.2024} & \textit{10.05.2024}\\
\hline
\endfirsthead
\multicolumn{7}{l}{Continued from previous page} \\[0pt]
\hline

Num & Documento & \textit{26.04.2024} & \textit{29.04.2024} & \textit{06.05.2024} & \textit{08.05.2024} & \textit{10.05.2024} \\[0pt]

\hline
\endhead
\hline\multicolumn{7}{r}{Continued on next page} \\
\endfoot
\endlastfoot
\hline
1 & 12345678 &  &  &  &  & \\
2 & 12345678 &  &  &  &  & \\
3 & 12345678 &  &  &  &  & \\
4 & 12345678 &  &  &  &  & \\
\end{longtable}

That compiles with TL2023.

Is this the same result as yours.

In my particular use case (I want \hline always) the solution is 

--8<---------------cut here---------------start------------->8---
(defun my-latex-insert-hline-always (row backend info)
  "Add a hline to every row when exporting to  LaTeX."
  (when (org-export-derived-backend-p backend 'latex)
    (replace-regexp-in-string "\\\\\\\\\\[0pt\\]\\|\\\\\\\\" "\\\\\\\\ \\\\hline" row)))
--8<---------------cut here---------------end--------------->8---





-- 
I strongly condemn Hamas heinous despicable pogroms/atrocities on Israel
I strongly condemn Putin's war of aggression against Ukraine.
I support to deliver weapons to Ukraine's military. 
I support the EU and NATO membership of Ukraine. 


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5673 bytes --]

^ permalink raw reply	[relevance 11%]

* [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export
@ 2024-01-02 23:46 20% Juan Manuel Macías
  2024-01-13 15:08 10% ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2024-01-02 23:46 UTC (permalink / raw)
  To: orgmode

Hi,

I recently discovered that if the last line of a LaTeX 'verse'
environment ends in '\\[0pt]', the space after the environment is
drastically altered. The space after a 'verse' environment (which is a
modified list environment) must be equivalent to
\partopsep+\topsep+\baselineskip. I have done the test with a document,
defining a rectangle of that height with tikz, where you can see the
difference in vertical space with and without '\\[0pt]':

https://i.imgur.com/khbboDZ.png

Naturally, this implies an issue when exporting the verse block to
LaTeX, since the presence of the '\\[0pt]' string alters the expected
result in the compiled PDF. My suggestion is that the last line of the
verse block is not exported with either the string '[0pt]' or the line
break mark '\\', since it makes no sense for that mark to be there: it
is the end of a paragraph and the very end of the environment.

Can anyone think of a possible scenario where removing the '\\[0pt]' in
the last line would cause a problem? If not, I might send a patch in the
next few days. (I'm afraid that going back to abusing
replace-regexp-in-string. I can't think of any other more elegant
solution...).

Best regards,

Juan Manuel 


-- 
Juan Manuel Macías -- Composición tipográfica, tratamiento de datos, diseño editorial y ortotipografía



^ permalink raw reply	[relevance 20%]

* [SOLVED] (was: org table export to latex, longtable, code does not compile)
  2024-01-02 17:20 10% org table export to latex, longtable, code does not compile Uwe Brauer
@ 2024-01-02 17:58  8% ` Uwe Brauer
    1 sibling, 0 replies; 200+ results
From: Uwe Brauer @ 2024-01-02 17:58 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 562 bytes --]

>>> "UB" == Uwe Brauer <oub@mat.ucm.es> writes:

> Hi

> I am running emacs 29 and org mode 9.6.9

> I have set (setq org-latex-line-break-safe "\\\\")

> Nevertheless the following example 

This helped


(defun my-latex-insert-hline-always (row backend info)
  "Add a hline to every row when exporting to  LaTeX."
  (when (org-export-derived-backend-p backend 'latex)
    (replace-regexp-in-string "\\\\\\\\\\[0pt\\]\\|\\\\\\\\" "\\\\\\\\ \\\\hline" row)))

(add-to-list 'org-export-filter-table-row-functions 'my-latex-insert-hline-always)

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5673 bytes --]

^ permalink raw reply	[relevance 8%]

* org table export to latex, longtable, code does not compile
@ 2024-01-02 17:20 10% Uwe Brauer
  2024-01-02 17:58  8% ` [SOLVED] (was: org table export to latex, longtable, code does not compile) Uwe Brauer
    0 siblings, 2 replies; 200+ results
From: Uwe Brauer @ 2024-01-02 17:20 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 2887 bytes --]



Hi

I am running emacs 29 and org mode 9.6.9

I have set (setq org-latex-line-break-safe "\\\\")

Nevertheless the following example 
#+begin_src 
#+ATTR_LATEX: :environment longtable
| / |  <> |        <> | <>           | <>           | <>           | <>           | <>           |
|---+-----+-----------+--------------+--------------+--------------+--------------+--------------|
|   | Num | Documento | <2024-04-26> | <2024-04-29> | <2024-05-06> | <2024-05-08> | <2024-05-10> |
|---+-----+-----------+--------------+--------------+--------------+--------------+--------------|
|   |   1 |  12345678 |              |              |              |              |              |
|   |   2 |  12345678 |              |              |              |              |              |
|   |   3 |  12345678 |              |              |              |              |              |
|   |   4 |  12345678 |              |              |              |              |              |
#+end_src

Will be translated to 

#+begin_src 

\begin{longtable}{|r|r|l|l|l|l|l|}
\hline
Num & Documento & \textit{26.04.2024} & \textit{29.04.2024} & \textit{06.05.2024} & \textit{08.05.2024} & \textit{10.05.2024}\\ \hline
\hline
\endfirsthead
\multicolumn{7}{l}{Continued from previous page} \\ \hline[0pt]
\hline

Num & Documento & \textit{26.04.2024} & \textit{29.04.2024} & \textit{06.05.2024} & \textit{08.05.2024} & \textit{10.05.2024} \\ \hline[0pt]

\hline
\endhead
\hline\multicolumn{7}{r}{Continued on next page} \\ \hline
\endfoot
\endlastfoot
\hline
1 & 12345678 &  &  &  &  & \\ \hline
2 & 12345678 &  &  &  &  & \\ \hline
3 & 12345678 &  &  &  &  & \\ \hline
4 & 12345678 &  &  &  &  & \\ \hline
\end{longtable}
#+end_src


#+begin_src 

And this does not compile for TL2023, it gives the following error:
Overfull \hbox (64.42285pt too wide) in alignment at lines 28--32
 [] [] [] [] [] [] [] 
./problem.tex:34: Misplaced \noalign.
\hline ->\noalign 
                  {\ifnum 0=`}\fi \penalty \@M \futurelet \@let@token \LT@@h...l.34 \hline
           
./problem.tex:35: Misplaced \omit.
\multispan ->\omit 
                   \@multispan 
l.35 
     
./problem.tex:38: Misplaced \noalign.
\hline ->\noalign 
                  {\ifnum 0=`}\fi \penalty \@M \futurelet \@let@token \LT@@h...l.38 \hline
           
./problem.tex:39: Misplaced \omit.
\multispan ->\omit 
                   \@multispan 
l.39 \endhead
#+end_src
             


The problem are the lines \hline[0pt]

I can query replace them, but is there any other solution.

Regards

Uwe Brauer 
-- 
I strongly condemn Hamas heinous despicable pogroms/atrocities on Israel
I strongly condemn Putin's war of aggression against Ukraine.
I support to deliver weapons to Ukraine's military. 
I support the EU and NATO membership of Ukraine. 


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5673 bytes --]

^ permalink raw reply	[relevance 10%]

* [BUG] ox-odt.el overrides auto-mode-alist defaults [9.6.6 (release_9.6.6 @ /usr/share/emacs/29.1/lisp/org/)]
@ 2023-12-09  5:18  3% Peter Prevos
  0 siblings, 0 replies; 200+ results
From: Peter Prevos @ 2023-12-09  5:18 UTC (permalink / raw)
  To: emacs-orgmode



Remember to cover the basics, that is, what you expected to happen 
and
what in fact did happen.  You don't know how to make a good 
report?  See

     https://orgmode.org/manual/Feedback.html#Feedback

Your bug report will be posted to the Org mailing list.
------------------------------------------------------------------------

Hi,

ox-odt.el overrides the auto-mode-alist settings and instructs 
Emacs to open od[fgpst] files in archive-mode instead of 
doc-view-mode.

This line can be removed because it prevents Emacs from opening 
LibreOffice files.

The test is to open a LibreOffice file in vanilla Emacs and when 
ox-odt.el is activated.

Regards

P:)

Emacs  : GNU Emacs 29.1 (build 1, x86_64-pc-linux-gnu, GTK+ 
Version 3.24.38, cairo version 1.17.8)
Package: Org mode version 9.6.6 (release_9.6.6 @ 
/usr/share/emacs/29.1/lisp/org/)

current state:
==============
(setq
 org-agenda-prefix-format '((dashboard-agenda . " %i %-12:c %s ")
			    (agenda . " %i %-12:c%?-12t% s")
			    (todo . " %i %-12:c")
			    (tags . " %i %-12:c")
			    (search . " %i %-12:c"))
 org-archive-location 
 "~/Documents/notes/20230604T152600--gtd-archive__productivity.org::* 
 From %s"
 org-link-elisp-confirm-function 'yes-or-no-p
 org-directory "/home/peter/Documents/notes/"
 org-cite-insert-processor 'citar
 org-hide-emphasis-markers t
 org-bibtex-headline-format-function #[257 "\300\236A\207" 
 [:title] 3 "\n\n(fn ENTRY)"]
 org-log-done 'time
 org-capture-bookmark nil
 org-agenda-custom-commands '(("n" "Netherlands" ((tags-todo 
 "nl"))
			       ((org-agenda-files
				 (denote-directory-files-matching-regexp 
				 "_gtd")
				 )
				)
			       )
			      ("h" "Third Hemisphere"
			       ((agenda ""
				 ((org-agenda-span 3)
				  (org-agenda-start-on-weekday 
				  nil))
				 )
				(todo "NEXT"
				 ((org-agenda-overriding-header
				   "Next Actions")
				  )
				 )
				(todo "WAITING"
				 ((org-agenda-overriding-header
				   "Waiting")
				  )
				 )
				(stuck))
			       ((org-agenda-files
				 (cl-remove-if
				  (lambda (f)
				   (string-match-p "_cw" f))
				  (denote-directory-files-matching-regexp 
				  "_gtd")
				  )
				 )
				)
			       )
			      ("p" "Projects"
			       ((todo "PROJECT")
				(stuck ""
				 ((org-agenda-sorting-strategy
				   '(alpha-up priority-down))
				  )
				 )
				)
			       )
			      ("c" "Work"
			       ((agenda ""
				 ((org-agenda-span 7)
				  (org-agenda-start-on-weekday 1))
				 )
				(todo "NEXT") (todo "WAITING")
				(stuck))
			       ((org-agenda-files
				 (denote-directory-files-matching-regexp 
				 "_cw.*_gtd")
				 )
				)
			       )
			      )
 org-log-into-drawer t
 org-agenda-skip-scheduled-if-done t
 org-agenda-files 
 '("/home/peter/Documents/notes/20220718T190010--notes-inbox__gtd.org" 
 "/home/peter/Documents/notes/20220719T125424--third-hemisphere-action-plan__gtd.org" 
 "/home/peter/Documents/notes/20230104T060726--lucid-manager-action-plan__gtd_lucidmanager.org" 
 "/home/peter/Documents/notes/20230104T193809--horizon-of-reason-action-plan__gtd.org" 
 "/home/peter/Documents/notes/20230115T083737--magic-perspectives-action-plan__gtd_magic.org" 
 "/home/peter/Documents/notes/20230821T094002--nederland__gjpc_gtd_nl.org" 
 "/home/peter/Documents/notes/20230925T150445--coliban-water-actions__cw_gtd.org")
 org-capture-templates '(("f" "Fleeting note" item
			  (file+headline org-default-notes-file
			   "Notes")
			  "- %?")
			 ("t" "New task" entry
			  (file+headline org-default-notes-file
			   "Tasks")
			  "* TODO %i%?")
			 ("e" "Email task" entry
			  (file+headline org-default-notes-file
			   "Tasks")
			  "* TODO %:fromname: %a %?\nDEADLINE: 
			  %(org-insert-time-stamp (org-read-date 
			  nil t \"+2d\"))")
			 )
 org-persist-after-read-hook 
 '(org-element--cache-persist-after-read)
 org-export-before-parsing-hook '(org-attach-expand-links)
 org-cycle-tab-first-hook '(org-babel-hide-result-toggle-maybe
			    org-babel-header-arg-expand)
 org-startup-with-latex-preview t
 org-default-notes-file 
 "/home/peter/Documents/notes/20220718T190010--notes-inbox__gtd.org"
 org-archive-hook '(org-attach-archive-delete-maybe)
 org-cite-follow-processor 'citar
 org-odt-format-inlinetask-function 
 'org-odt-format-inlinetask-default-function
 org-ascii-format-drawer-function #[771 "\207" [] 4 "\n\n(fn NAME 
 CONTENTS WIDTH)"]
 org-cycle-hook '(org-cycle-hide-archived-subtrees
		  org-cycle-show-empty-lines
		  org-cycle-optimize-window-after-visibility-change
		  org-cycle-display-inline-images)
 org-export-with-broken-links t
 org-persist-before-read-hook 
 '(org-element--cache-persist-before-read)
 org-link-from-user-regexp "\\<peter@xps9315\\>\\|\\<Peter 
 Prevos\\>"
 org-image-actual-width '(450)
 org-mode-hook '(org-autolist-mode writegood-mode citar-capf-setup
		 #[0 "\301\211\207"
		   [imenu-create-index-function 
		   org-imenu-get-tree]
		   2]
		 org-fragtog-mode global-org-modern-mode
		 org-appear-mode mixed-pitch-mode
		 #[0 "\300\301\302\303\304$\207"
		   [add-hook change-major-mode-hook
		    org-fold-show-all append local]
		   5]
		 #[0 "\300\301\302\303\304$\207"
		   [add-hook change-major-mode-hook
		    org-babel-show-result-all append local]
		   5]
		 org-babel-result-hide-spec
		 org-babel-hide-all-hashes)
 org-babel-load-languages '((emacs-lisp . t) (R . t) (python . t)
			    (julia . t) (shell . t) (latex . t))
 org-agenda-skip-deadline-if-done t
 org-cite-csl-styles-dir "~/Documents/library/csl/"
 org-modern-timestamp nil
 org-modern-checkbox nil
 org-latex-format-drawer-function #[514 "\207" [] 3 "\n\n(fn _ 
 CONTENTS)"]
 org-ellipsis " ↲"
 org-latex-format-headline-function 
 'org-latex-format-headline-default-function
 org-confirm-shell-link-function 'yes-or-no-p
 org-html-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME 
 CONTENTS)"]
 outline-isearch-open-invisible-function 
 'outline-isearch-open-invisible
 org-use-sub-superscripts "{}"
 org-export-with-todo-keywords nil
 org-stuck-projects '("/PROJECT" ("NEXT" "WAITING") nil
		      "SCHEDULED\\|DEADLINE")
 org-log-repeat nil
 org-startup-indented t
 org-fold-catch-invisible-edits 'error
 org-latex-classes '(("apa6"
		      "\\documentclass[a4paper, jou, 
		      11pt]{apa6}\n\\usepackage[nodoi]{apacite}\n\\usepackage[british]{babel}\n\\usepackage{inputenc}\n\\usepackage{amsmath}\n\\usepackage{graphicx}\n\\usepackage{csquotes}\n\\usepackage[hyphens]{url}\n\\usepackage[T1]{fontenc}\n\\usepackage{lmodern}\n\\usepackage{hyperref}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}"))
		     ("trade"
		      "\\documentclass[11pt, twoside]{memoir}\n 
		      \\setstocksize{9in}{6in}\n 
		      \\settrimmedsize{\\stockheight}{\\stockwidth}{*}\n 
		      \\setlrmarginsandblock{2cm}{2cm}{*} % Left 
		      and right margin\n 
		      \\setulmarginsandblock{2cm}{2cm}{*} % Upper 
		      and lower margin\n 
		      \\checkandfixthelayout\n 
		      \\setcounter{tocdepth}{0}\n 
		      \\OnehalfSpacing\n    \\usepackage{times}\n 
		      \\chapterstyle{bianchi}\n 
		      \\setsecheadstyle{\\normalfont \\raggedright 
		      \\textbf}\n 
		      \\setsubsecheadstyle{\\normalfont 
		      \\raggedright \\emph}\n 
		      \\setsubsubsecheadstyle{\\normalfont\\centering}\n 
		      \\usepackage[font={small, it}]{caption}\n 
		      \\usepackage{subcaption}\n 
		      \\captionsetup[subfigure]{justification=centering}\n 
		      \\usepackage{pdfpages}\n 
		      \\pagestyle{myheadings}\n 
		      \\usepackage{ccicons}\n 
		      \\usepackage{nicefrac}\n 
		      \\usepackage[authoryear]{natbib}\n 
		      \\bibliographystyle{apalike}\n 
		      \\usepackage{nohyperref}\n 
		      \\usepackage{tikz}\n 
		      \\usetikzlibrary{shapes.geometric, calc, 
		      knots}\n    \\usepackage{svg}"
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" .
		       "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("crc"
		      "\\documentclass[krantz2]{krantz}\n 
		      \\usepackage{lmodern}\n 
		      \\usepackage[authoryear]{natbib}\n 
		      \\usepackage{nicefrac}\n 
		      \\usepackage[bf,singlelinecheck=off]{caption}\n 
		      \\captionsetup[table]{labelsep=space}\n 
		      \\captionsetup[figure]{labelsep=space}\n 
		      \\usepackage{Alegreya}\n 
		      \\usepackage[scale=.8]{sourcecodepro}\n 
		      \\usepackage[breaklines=true]{minted}\n 
		      \\usepackage{rotating}\n 
		      \\usepackage[notbib, 
		      nottoc,notlot,notlof]{tocbibind}\n 
		      \\usepackage{amsfonts, tikz, tikz-layers}\n 
		      \\usetikzlibrary{fadings, quotes, shapes, 
		      calc, decorations.markings}\n 
		      \\usetikzlibrary{patterns, shadows.blur}\n 
		      \\usetikzlibrary{shapes,shapes.geometric,positioning}\n 
		      \\usetikzlibrary{arrows, arrows.meta, 
		      backgrounds}\n        \\usepackage{imakeidx} 
		      \\makeindex[intoc]\n 
		      \\renewcommand{\\textfraction}{0.05}\n 
		      \\renewcommand{\\topfraction}{0.8}\n 
		      \\renewcommand{\\bottomfraction}{0.8}\n 
		      \\renewcommand{\\floatpagefraction}{0.75}\n 
		      \\renewcommand{\\eqref}[1]{(Equation 
		      \\ref{#1})}\n 
		      \\renewcommand{\\LaTeX}{LaTeX}"
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\paragraph*{%s}"))
		     ("magictrick"
		      "\\documentclass[11pt, a4paper, twocolumn, 
		      twoside]{article}\n\\usepackage{ccicons}\n\\usepackage{pdfpages}\n\\usepackage{times}\n\\usepackage{helvet}\n\\usepackage{geometry}\n\\geometry{a4paper, 
		      total={170mm,250mm}, left=20mm, top=30mm}\n% 
		      header 2008 x 332 
		      px\n\\usepackage{titlesec}\n\\titleformat{\\section}\n 
		      {\\bfseries}{\\thesection}{1em}{}\n\\titleformat{\\subsection}\n 
		      {\\itshape}{\\thesection}{1em}{}\n\\usepackage{fancyhdr}\n\\usepackage[font={small, 
		      it}, 
		      labelformat=empty]{caption}\n\\usepackage[hidelinks]{hyperref}\n\\pagestyle{fancy}\n\\renewcommand{\\headrulewidth}{0pt}\n\\renewcommand{\\footrulewidth}{0pt}\n\\setlength{\\parskip}{1em}\n\\renewcommand{\\baselinestretch}{1.1}\n\\setlength\\headheight{100.0pt}\n\\addtolength{\\textheight}{-100.0pt}\n\\fancyhead[LO]{\\Large{\\textsf{Magic 
		      Perspectives Presents}} 
		      \\includegraphics[width=\\textwidth]{header}}\n\\fancyhead[LE]{\\includegraphics[width=0.5\\textwidth]{header}}\n\\lfoot{Peter 
		      Prevos}\n\\rfoot{\\href{https://magicperspectives.net}{magicperspectives.net}}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}"))
		     ("ebook"
		      "\\documentclass[11pt, 
		      oneside]{memoir}\n\\setstocksize{9in}{6in}\n\\settrimmedsize{\\stockheight}{\\stockwidth}{*}\n\\setlrmarginsandblock{2cm}{2cm}{*} 
		      % Left and right 
		      margin\n\\setulmarginsandblock{2cm}{2cm}{*} 
		      % Upper and lower 
		      margin\n\\checkandfixthelayout\n\\usepackage{times}\n\\OnehalfSpacing\n\\usepackage[authoryear]{natbib}\n\\bibliographystyle{apalike}\n\\setlength{\\bibsep}{1pt}\n\\usepackage[raggedright]{sidecap}\n\\setsecheadstyle{\\normalfont 
		      \\raggedright 
		      \\textbf}\n\\setsubsecheadstyle{\\normalfont 
		      \\raggedright 
		      \\emph}\n\\usepackage{subcaption} 
		      \n\\usepackage[font={small, 
		      it}]{caption}\n\\captionsetup[subfigure]{justification=centering}\n\\usepackage{pdfpages}\n\\usepackage[unicode=true,\n 
		      bookmarks=true,bookmarksnumbered=false,bookmarksopen=true,\n 
		      bookmarksopenlevel=1, 
		      breaklinks=true,pdfborder={0 0 
		      0},backref=false,colorlinks=false,pdfborderstyle={/S/U/W 
		      .5}, allbordercolors={.8 .8 
		      .8}]{hyperref}\n\\pagestyle{myheadings}\n\\setcounter{tocdepth}{0}\n\\usepackage{ccicons}\n\\usepackage{nicefrac}\n"
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" .
		       "\\subsubsection*{%s}")
		      )
		     ("article"
		      "\\documentclass[10pt]{article}\n 
		      \\usepackage{tgpagella,eulervm}\n 
		      \\usepackage{nicefrac}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" .
		       "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("article" "\\documentclass[11pt]{article}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" .
		       "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("report" "\\documentclass[11pt]{report}"
		      ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" .
		       "\\subsubsection*{%s}")
		      )
		     ("book" "\\documentclass[11pt]{book}"
		      ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" .
		       "\\subsubsection*{%s}")
		      )
		     )
 org-odt-format-headline-function 
 'org-odt-format-headline-default-function
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-cycle-hide-block-startup t
 org-babel-tangle-lang-exts '(("latex" . "tex") ("julia" . "jl")
			      ("python" . "py")
			      ("emacs-lisp" . "el") ("elisp" 
			      . "el"))
 org-src-mode-hook '(org-src-babel-configure-edit-buffer
		     org-src-mode-configure-edit-buffer)
 org-confirm-elisp-link-function 'yes-or-no-p
 org-agenda-window-setup 'current-window
 org-latex-src-block-backend 'minted
 org-cycle-separator-lines 0
 org-cite-activate-processor 'citar
 org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAITING(w@/!)"
		      "PROJECT(p)" "GOAL(g)" "|" "DONE(d/!)"
		      "CANCELLED(c@/!)")
		     )
 org-latex-logfiles-extensions '("lof" "lot" "tex~" "aux" "idx"
				 "log" "out" "toc" "nav" "snm" 
				 "vrb"
				 "dvi" "fdb_latexmk" "blg" "brf"
				 "fls" "entoc" "ps" "spl" "bbl"
				 "tex" "bcf")
 org-structure-template-alist '(("ss" . "src shell\n")
				("sr" . "src R\n")
				("sp" . "src python\n")
				("se" . "src elisp\n")
				("a" . "export ascii")
				("c" . "center") ("C" . "comment")
				("e" . "example") ("E" . "export")
				("h" . "export html")
				("l" . "export latex")
				("q" . "quote") ("s" . "src")
				("v" . "verse"))
 org-pretty-entities t
 org-modern-block-name nil
 org-speed-command-hook '(org-speed-command-activate
			  org-babel-speed-command-activate)
 org-html-format-inlinetask-function 
 'org-html-format-inlinetask-default-function
 org-ascii-format-inlinetask-function 
 'org-ascii-format-inlinetask-default
 org-modern-mode-hook '(org-modern-mode-set-explicitly)
 org-odt-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME 
 CONTENTS)"]
 org-confirm-babel-evaluate nil
 org-fold-core-isearch-open-function 
 'org-fold-core--isearch-reveal
 org-export-with-smart-quotes t
 org-modern-keyword nil
 org-cite-export-processors '((latex natbib "apalike2" 
 "authoryear")
			      (t csl "apa6.csl"))
 org-preview-latex-default-process 'dvisvgm
 org-latex-format-inlinetask-function 
 'org-latex-format-inlinetask-default-function
 org-persist-before-write-hook 
 '(org-element--cache-persist-before-write)
 org-tab-first-hook '(org-babel-hide-result-toggle-maybe
		      org-babel-header-arg-expand)
 org-export-with-toc nil
 org-link-shell-confirm-function 'yes-or-no-p
 org-agenda-finalize-hook '(org-modern-agenda)
 org-babel-pre-tangle-hook '(save-buffer)
 org-agenda-loop-over-headlines-in-active-region nil
 org-cite-global-bibliography 
 '("/home/peter/Documents/library/horizon-of-reason.bib" 
 "/home/peter/Documents/library/lucidmanager.bib" 
 "/home/peter/Documents/library/magic-science.bib" 
 "/home/peter/Documents/library/magic-tricks.bib" 
 "/home/peter/Documents/library/third-hemisphere.bib" 
 "/home/peter/Documents/library/zotero.bib")
 org-occur-hook '(org-first-headline-recenter)
 org-capture-after-finalize-hook 
 '(denote-org-capture-delete-empty-file)
 org-export-with-drawers nil
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-odt-preferred-output-format "doc"
 org-link-parameters '(("attachment" :follow org-attach-follow
			:complete org-attach-complete-link)
		       ("mu4e" :follow mu4e-org-open :store
			mu4e-org-store-link)
		       ("helpful" :store helpful--org-link-store)
		       ("eww" :follow org-eww-open :store
			org-eww-store-link)
		       ("rmail" :follow org-rmail-open :store
			org-rmail-store-link)
		       ("mhe" :follow org-mhe-open :store
			org-mhe-store-link)
		       ("irc" :follow org-irc-visit :store
			org-irc-store-link :export org-irc-export)
		       ("info" :follow org-info-open :export
			org-info-export :store org-info-store-link
			:insert-description
			org-info-description-as-command)
		       ("gnus" :follow org-gnus-open :store
			org-gnus-store-link)
		       ("docview" :follow org-docview-open :export
			org-docview-export :store
			org-docview-store-link)
		       ("bbdb" :follow org-bbdb-open :export
			org-bbdb-export :complete
			org-bbdb-complete-link :store
			org-bbdb-store-link)
		       ("w3m" :store org-w3m-store-link)
		       ("doi" :follow org-link-doi-open :export
			org-link-doi-export)
		       ("hugo" :complete
			(lambda nil
			 (concat "{{% ref "
			  (file-name-nondirectory
			   (read-file-name "File: "))
			  " %}}")
			 )
			:follow org-hugo-followlink)
		       ("bibtex" :follow org-bibtex-open :store
			org-bibtex-store-link)
		       ("id" :follow org-id-open)
		       ("nov" :follow nov-org-link-follow :store
			nov-org-link-store)
		       ("denote" :follow denote-link-ol-follow 
		       :face
			denote-faces-link :complete
			denote-link-ol-complete :store
			denote-link-ol-store :export
			denote-link-ol-export)
		       ("elfeed" :follow elfeed-link-open :store
			elfeed-link-store-link)
		       ("file+sys") ("file+emacs")
		       ("shell" :follow org-link--open-shell)
		       ("news" :follow
			#[514 "\301\300\302Q\"\207"
			  ["news" browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("mailto" :follow
			#[514 "\301\300\302Q\"\207"
			  ["mailto" browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("https" :follow
			#[514 "\301\300\302Q\"\207"
			  ["https" browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("http" :follow
			#[514 "\301\300\302Q\"\207"
			  ["http" browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("ftp" :follow
			#[514 "\301\300\302Q\"\207"
			  ["ftp" browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("help" :follow helpful--org-link-follow
			:store org-link--store-help)
		       ("file" :complete org-link-complete-file)
		       ("elisp" :follow org-link--open-elisp))
 org-html-format-headline-function 
 'org-html-format-headline-default-function
 org-agenda-start-with-follow-mode t
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-modern-table nil
 org-agenda-restore-windows-after-quit t
 org-agenda-remove-tags t
 org-num-format-function 'org-num-default-format
 org-agenda-include-diary t
 org-modern-table-horizontal nil
 org-startup-with-inline-images t
 org-latex-pdf-process '(“pdflatex -interaction nonstopmode
			 -output-directory %o %f” "bibtex %b"
			 “pdflatex -shell-escape -interaction
			 nonstopmode -output-directory %o %f”
			 “pdflatex -shell-escape -interaction
			 nonstopmode -output-directory %o %f”)
 org-list-allow-alphabetical t
 )
-- 
Dr Peter Prevos
---------------
peterprevos.com


^ permalink raw reply	[relevance 3%]

* Re: Regression in latex export of tables?
  2023-11-03  2:30  8%         ` Max Nikulin
@ 2023-11-03  3:01  8%           ` Vikas Rawal
  0 siblings, 0 replies; 200+ results
From: Vikas Rawal @ 2023-11-03  3:01 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 833 bytes --]

On 03/11/2023 07:58, Vikas Rawal wrote:
> Earlier version gives me this:
> \begin{center}
> \begin{tabular}{ll}
> (a,b) & open interval\\\empty
> [0,1] & closed interval\\\empty

It was changed to avoid your inconvenience:
https://list.orgmode.org/874jw2conh.fsf@posteo.net/T/#uOh, wow! Thank you all for having been so considerate of needs of even individual users like this. I did not notice this.
Org mode community does not cease to amaze me. 
> (defun org-export-midrule-filter-latex (row backend info)
>   (replace-regexp-in-string
> "\\(<mid>\\([[:blank:]]+\\&\\)+\\)[[:blank:]]\\\\\\\\" "\\\\midrule" row))
>
> Now my \midrule becomes \midrule[0pt].

Sorry, but your have to adjust the pattern and the replacement string to
allow either optional \empty or [0pt].Done

Thank you once again.

Vikas
 

[-- Attachment #2: Type: text/html, Size: 1206 bytes --]

^ permalink raw reply	[relevance 8%]

* Re: Regression in latex export of tables?
  2023-11-03  0:58 11%       ` Vikas Rawal
@ 2023-11-03  2:30  8%         ` Max Nikulin
  2023-11-03  3:01  8%           ` Vikas Rawal
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2023-11-03  2:30 UTC (permalink / raw)
  To: emacs-orgmode

On 03/11/2023 07:58, Vikas Rawal wrote:
> Earlier version gives me this:
> \begin{center}
> \begin{tabular}{ll}
> (a,b) & open interval\\\empty
> [0,1] & closed interval\\\empty

It was changed to avoid your inconvenience:
https://list.orgmode.org/874jw2conh.fsf@posteo.net/T/#u
Juan Manuel Macías. Re: Line breaks and brackets in LaTeX export. Mon, 
17 Oct 2022 18:04:34 +0000

That moment there was no hope that tabularray would support \empty out 
of the box. Perhaps some stable Linux distribution still have its 
version unaware of \empty.

> (defun org-export-midrule-filter-latex (row backend info)
>    (replace-regexp-in-string 
> "\\(<mid>\\([[:blank:]]+\\&\\)+\\)[[:blank:]]\\\\\\\\" "\\\\midrule" row))
> 
> Now my \midrule becomes \midrule[0pt].

Sorry, but your have to adjust the pattern and the replacement string to 
allow either optional \empty or [0pt].

I still do not see a better solution that does not require substantional 
changes of the org-export framework.



^ permalink raw reply	[relevance 8%]

* Re: Regression in latex export of tables?
  2023-11-02  9:29  8%     ` Fraga, Eric
@ 2023-11-03  0:58 11%       ` Vikas Rawal
  2023-11-03  2:30  8%         ` Max Nikulin
  0 siblings, 1 reply; 200+ results
From: Vikas Rawal @ 2023-11-03  0:58 UTC (permalink / raw)
  To: Fraga, Eric; +Cc: Max Nikulin, emacs-orgmode@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1202 bytes --]


On Thursday, November 02, 2023 14:59 IST, "Fraga, Eric" <e.fraga@ucl.ac.uk> wrote:
 On Wednesday, 1 Nov 2023 at 19:04, Vikas Rawal wrote:
> I am sorry, but I do not understand what are you pointing at. This is
> what I get:
>
> ----
> \begin{center}
> \begin{tabular}{ll}
> (a,b) & open interval\\[0pt]
> [0,1] & closed interval\\[0pt]
> \end{tabular}
> \end{center}
> \end{document}
> ----

I think the point is that without the [0pt], the following line's [0,1]
gets interpreted as a length parameter for the line break, \\.

--
: Eric S Fraga, with org release_9.6.6-418-g294a4d in Emacs 30.0.50Earlier version gives me this:
\begin{center}
\begin{tabular}{ll}
(a,b) & open interval\\\empty
[0,1] & closed interval\\\empty
\end{tabular}
\end{center}
\end{document}

I have several export filters that break because of this [0pt]. For example, I use <mid> in a table row (created by an R source code) to mark wherever I want a midrule using this:

(defun org-export-midrule-filter-latex (row backend info)
  (replace-regexp-in-string "\\(<mid>\\([[:blank:]]+\\&\\)+\\)[[:blank:]]\\\\\\\\" "\\\\midrule" row))

Now my \midrule becomes \midrule[0pt].

Vikas
 

[-- Attachment #2: Type: text/html, Size: 1512 bytes --]

^ permalink raw reply	[relevance 11%]

* Re: Regression in latex export of tables?
  2023-11-01 23:04 11%   ` Vikas Rawal
@ 2023-11-02  9:29  8%     ` Fraga, Eric
  2023-11-03  0:58 11%       ` Vikas Rawal
  0 siblings, 1 reply; 200+ results
From: Fraga, Eric @ 2023-11-02  9:29 UTC (permalink / raw)
  To: Vikas Rawal; +Cc: Max Nikulin, emacs-orgmode@gnu.org

On Wednesday,  1 Nov 2023 at 19:04, Vikas Rawal wrote:
> I am sorry, but I do not understand what are you pointing at. This is
> what I get:
>
> ----
> \begin{center}
> \begin{tabular}{ll}
> (a,b) & open interval\\[0pt]
> [0,1] & closed interval\\[0pt]
> \end{tabular}
> \end{center}
> \end{document}
> ----

I think the point is that without the [0pt], the following line's [0,1]
gets interpreted as a length parameter for the line break, \\.

-- 
: Eric S Fraga, with org release_9.6.6-418-g294a4d in Emacs 30.0.50

^ permalink raw reply	[relevance 8%]

* Re: Regression in latex export of tables?
  2023-11-01 16:41  0% ` Max Nikulin
@ 2023-11-01 23:04 11%   ` Vikas Rawal
  2023-11-02  9:29  8%     ` Fraga, Eric
  0 siblings, 1 reply; 200+ results
From: Vikas Rawal @ 2023-11-01 23:04 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 680 bytes --]


On 01/11/2023 10:43, Vikas Rawal wrote:
> Both give this strage [0pt] at the end of every line of the table.
>
> ​​​​​​Is this by design? This seems to be something recent. Am I missing
> something.

If you believe that it is a regression then try to export something like

| (a,b) | open interval |
| [0,1] | closed interval |

https://list.orgmode.org/?q=%5B0pt%5D

 
I am sorry, but I do not understand what are you pointing at. This is what I get:

----
\begin{center}
\begin{tabular}{ll}
(a,b) & open interval\\[0pt]
[0,1] & closed interval\\[0pt]
\end{tabular}
\end{center}
\end{document}
----

What is this [0pt] at the end?

 

[-- Attachment #2: Type: text/html, Size: 928 bytes --]

^ permalink raw reply	[relevance 11%]

* Re: Regression in latex export of tables?
  2023-11-01  3:43 12% Regression in latex export of tables? Vikas Rawal
  2023-11-01  7:32  8% ` Vikas Rawal
@ 2023-11-01 16:41  0% ` Max Nikulin
  2023-11-01 23:04 11%   ` Vikas Rawal
  1 sibling, 1 reply; 200+ results
From: Max Nikulin @ 2023-11-01 16:41 UTC (permalink / raw)
  To: Vikas Rawal, emacs-orgmode

On 01/11/2023 10:43, Vikas Rawal wrote:
> Both give this strage [0pt] at the end of every line of the table.
> 
> ​​​​​​Is this by design? This seems to be something recent. Am I missing 
> something.

If you believe that it is a regression then try to export something like

| (a,b) | open interval   |
| [0,1] | closed interval |

https://list.orgmode.org/?q=%5B0pt%5D



^ permalink raw reply	[relevance 0%]

* Re: Regression in latex export of tables?
  2023-11-01  3:43 12% Regression in latex export of tables? Vikas Rawal
@ 2023-11-01  7:32  8% ` Vikas Rawal
  2023-11-01 16:41  0% ` Max Nikulin
  1 sibling, 0 replies; 200+ results
From: Vikas Rawal @ 2023-11-01  7:32 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 526 bytes --]

I am seeing a peculiar problem, and I would appreciate if somebody could check whether this is a bug or I am missing something.

The following table exports with a [0pt] at the end of each line.I can confirm that the problem disappears if I move to the following version of org-mode:

commit bed47b437d8cde7a98bafdb07996e248b40f70e6 (HEAD -> main, origin/main)
Author: Rudolf Adamkovič <salutis@me.com>
Date:   Fri Oct 21 14:48:56 2022 +0200

Clearly, the problem has appeared more recently than this.

Vikas
 

[-- Attachment #2: Type: text/html, Size: 677 bytes --]

^ permalink raw reply	[relevance 8%]

* Regression in latex export of tables?
@ 2023-11-01  3:43 12% Vikas Rawal
  2023-11-01  7:32  8% ` Vikas Rawal
  2023-11-01 16:41  0% ` Max Nikulin
  0 siblings, 2 replies; 200+ results
From: Vikas Rawal @ 2023-11-01  3:43 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 945 bytes --]


Hi all,

I am seeing a peculiar problem, and I would appreciate if somebody could check whether this is a bug or I am missing something.

The following table exports with a [0pt] at the end of each line.

* Test
| A | B | C |
|---+---+---|
| 1 | 2 | 3 |
|   |   |   |


\section{Test}
\label{sec:orgb720d02}
\begin{center}
\begin{tabular}{rrr}
A & B & C\\[0pt]
\hline
1 & 2 & 3\\[0pt]
 &  & \\[0pt]
\end{tabular}
\end{center}
\end{document}

I have tried this by running emacs -q (to check if something in my config was messing up). With emacs -q, my org-version is: Org mode version 9.6.7 (release_9.6.7-13-g99cc96)
​​​If I use my .emacs.d, my org-version is: Org mode version 9.7-pre (release_9.6.10-906-gee0961

Both give this strage [0pt] at the end of every line of the table.

​​​​​​Is this by design? This seems to be something recent. Am I missing something.

Thanks,

Vikas

[-- Attachment #2: Type: text/html, Size: 1144 bytes --]

^ permalink raw reply	[relevance 12%]

* Re: Are 'placement' and 'float' "obsolete terms" in inline images exported to LaTeX?
  2023-10-06 16:29  0%         ` Ihor Radchenko
@ 2023-10-06 18:35  0%           ` Juan Manuel Macías
  0 siblings, 0 replies; 200+ results
From: Juan Manuel Macías @ 2023-10-06 18:35 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode

Ihor Radchenko writes:

>> In tables there is more consistency because :float is a float
>> environment (table or any arbitrary value) and :environment is a table
>> environment (tabular or any arbitrary value). Here :placement :options
>> and :align act as what is expected of them:
>>
>> #+ATTR_LaTeX: :environment foo :float var :placement [!h] :options [blah] :align cccc
>> |a|a|a|a|
>>
>> ===>
>>
>> \begin{var}[!h]
>> \centering
>> \begin{foo}[blah]{cccc}
>> a & a & a & a\\[0pt]
>> \end{foo}
>> \end{var}
>> \end{document}
>
> This is not documented and is possibly a bug.

I would say that it is the expected behavior: :float is for a float
environment and :environment is for the environment that builds the
table (by default tabular). According to the manual:

#+begin_quote
The table environments by default are not floats in LaTeX.  To make
them floating objects use =:float= with one of the following
options: =t= (for a default =table= environment), =sideways= (for a
=sidewaystable= environment), =multicolumn= [...] and
=nil=.  In addition to these three values, =:float= can pass through
any arbitrary value, for example a user-defined float type with the
=float= LaTeX package
#+end_quote

and (for :environment):

#+begin_quote
Set the default LaTeX table environment for the LaTeX export
backend to use when exporting Org tables.  Common LaTeX table
environments are provided by these packages: tabularx, longtable,
array, tabu, and bmatrix.  For packages, such as tabularx and tabu,
or any newer replacements
#+end_quote

The difference is that with images, except in cases of somewhat more
complex constructions where there are subfigures, there is only one
environment, "figure" by default or any other arbitrary one. There was a
commit a while ago, I don't remember when, that allowed :float to
support any arbitrary string as the float environment name, in images
and tables. In images ':float t' is figure (by default) and in tables it
is table (also by default).

Update: ah, I already have the commit located, because I also remember
that I myself sent a patch to update the documentation and correct a
regression that that commit introduced (:float t produced an environment
"t" (\begin{t}...\end{t}):

https://list.orgmode.org/878ruhrvfq.fsf@posteo.net/


^ permalink raw reply	[relevance 0%]

* Re: Are 'placement' and 'float' "obsolete terms" in inline images exported to LaTeX?
  2023-10-04 14:34  7%       ` Juan Manuel Macías
@ 2023-10-06 16:29  0%         ` Ihor Radchenko
  2023-10-06 18:35  0%           ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2023-10-06 16:29 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

Juan Manuel Macías <maciaschain@posteo.net> writes:

> Ihor Radchenko writes:
>
>> Further, we also provide :environment and :options attributes that do
>> the same thing, but without special treatment of standard
>> t/multicolumn/wrap/sideways/nil values in :float.
>
> t/multicolumn/wrap/sideways/nil... and any arbitrary value (see lines 14125
> and 14262 in org-manual.org).

My point is that actual "t", "multicolumn", "wrap", "sideways", and
"nil" LaTeX environments are not allowed.

>> So, it might be even better idea to extend :environment/:options
>> attributes to more elements - their names make more sense and the values
>> do not have a pre-defined special meanings.
>
> Currently it is not possible in inline images (if I don't miss anything) this:
>
> #+ATTR_LaTeX: :environment minipage :options {\textwidth}
> [[file:/usr/share/texmf-dist/tex/latex/mwe/example-image-a.jpg]]

Sure. But we might as well implement :environment support in addition to :float.

> Implementing :environment/:options here would result in redundancy with:
>
> #+ATTR_LaTeX: :float minipage :placement {\textwidth}
> [[file:/usr/share/texmf-dist/tex/latex/mwe/example-image-a.jpg]]
>
> which produces the same.

Sure. But didn't you motivate the change with the confusing _name_
:float? IMHO, :environment is more clear.

> In tables there is more consistency because :float is a float
> environment (table or any arbitrary value) and :environment is a table
> environment (tabular or any arbitrary value). Here :placement :options
> and :align act as what is expected of them:
>
> #+ATTR_LaTeX: :environment foo :float var :placement [!h] :options [blah] :align cccc
> |a|a|a|a|
>
> ===>
>
> \begin{var}[!h]
> \centering
> \begin{foo}[blah]{cccc}
> a & a & a & a\\[0pt]
> \end{foo}
> \end{var}
> \end{document}

This is not documented and is possibly a bug.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 0%]

* Re: Are 'placement' and 'float' "obsolete terms" in inline images exported to LaTeX?
  @ 2023-10-04 14:34  7%       ` Juan Manuel Macías
  2023-10-06 16:29  0%         ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2023-10-04 14:34 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode

Ihor Radchenko writes:

> Further, we also provide :environment and :options attributes that do
> the same thing, but without special treatment of standard
> t/multicolumn/wrap/sideways/nil values in :float.

t/multicolumn/wrap/sideways/nil... and any arbitrary value (see lines 14125
and 14262 in org-manual.org).

>>> What we might do it to introduce something like a new :wrap attribute:
>>>
>>> #+attr_latex: :wrap subfigure,{\textwidht}
>
> So, it might be even better idea to extend :environment/:options
> attributes to more elements - their names make more sense and the values
> do not have a pre-defined special meanings.

Currently it is not possible in inline images (if I don't miss anything) this:

#+ATTR_LaTeX: :environment minipage :options {\textwidth}
[[file:/usr/share/texmf-dist/tex/latex/mwe/example-image-a.jpg]]

Implementing :environment/:options here would result in redundancy with:

#+ATTR_LaTeX: :float minipage :placement {\textwidth}
[[file:/usr/share/texmf-dist/tex/latex/mwe/example-image-a.jpg]]

which produces the same.

In tables there is more consistency because :float is a float
environment (table or any arbitrary value) and :environment is a table
environment (tabular or any arbitrary value). Here :placement :options
and :align act as what is expected of them:

#+ATTR_LaTeX: :environment foo :float var :placement [!h] :options [blah] :align cccc
|a|a|a|a|

===>

\begin{var}[!h]
\centering
\begin{foo}[blah]{cccc}
a & a & a & a\\[0pt]
\end{foo}
\end{var}
\end{document}

-- 
Juan Manuel Macías

https://juanmanuelmacias.com

https://lunotipia.juanmanuelmacias.com

https://gnutas.juanmanuelmacias.com



^ permalink raw reply	[relevance 7%]

* [BUG] Previewing equations [9.6.6 (release_9.6.6 @ /usr/share/emacs/29.1/lisp/org/)]
@ 2023-09-24 21:47  3% Peter Prevos
  0 siblings, 0 replies; 200+ results
From: Peter Prevos @ 2023-09-24 21:47 UTC (permalink / raw)
  To: emacs-orgmode



Remember to cover the basics, that is, what you expected to happen 
and
what in fact did happen.  You don't know how to make a good 
report?  See

     https://orgmode.org/manual/Feedback.html#Feedback

Your bug report will be posted to the Org mailing list.
------------------------------------------------------------------------

 ■  Warning (org-element-cache): org-element--cache: Org parser 
 error in Infonomics II: Business Information Management and 
 Measurement::6190. Resetting.
 The error was: (error "Invalid search bound (wrong side of 
 point)")
 Backtrace:
"  backtrace-to-string(nil)
  org-element-at-point()
  org-back-to-heading(t)
  org-back-to-heading-or-point-min(t)
  org-get-property-block()
  org--property-local-values(\"LOG_INTO_DRAWER\" t)
  org-entry-get-with-inheritance(\"LOG_INTO_DRAWER\" t)
  org-entry-get(nil \"LOG_INTO_DRAWER\" inherit t)
  org-log-into-drawer()
  org-mode-flyspell-verify()
  flyspell-word()
  flyspell-post-command-hook()
"
 Please report this to Org mode mailing list (M-x 
 org-submit-bug-report).


Emacs  : GNU Emacs 29.1 (build 1, x86_64-pc-linux-gnu, GTK+ 
Version 3.24.38, cairo version 1.17.8)
Package: Org mode version 9.6.6 (release_9.6.6 @ 
/usr/share/emacs/29.1/lisp/org/)

current state:
==============
(setq
 org-agenda-prefix-format '((dashboard-agenda . " %i %-12:c %s ")
			    (agenda . " %i %-12:c%?-12t% s")
			    (todo . " %i %-12:c") (tags . " %i 
			    %-12:c")
			    (search . " %i %-12:c"))
 org-archive-location 
 "~/Documents/notes/20230604T152600--gtd-archive__productivity.org::* 
 From %s"
 org-link-elisp-confirm-function 'yes-or-no-p
 org-directory "/home/peter/Documents/notes/"
 org-cite-insert-processor 'citar
 org-hide-emphasis-markers t
 org-bibtex-headline-format-function #[257 "\300\236A\207" 
 [:title] 3 "\n\n(fn ENTRY)"]
 org-log-done 'time
 org-agenda-custom-commands '(("n" "Netherlands" ((tags-todo 
 "nl"))
			       ((org-agenda-files
				 (denote-directory-files-matching-regexp
				  "_gtd")
				 )
				)
			       )
			      ("h" "Third Hemisphere"
			       ((agenda ""
				 ((org-agenda-span 3)
				  (org-agenda-start-on-weekday 
				  nil))
				 )
				(todo "NEXT") (todo "WAITING") 
				(stuck))
			       ((org-agenda-files
				 (cl-remove-if
				  (lambda (f) (string-match-p 
				  "_cw" f))
				  (denote-directory-files-matching-regexp
				   "_gtd")
				  )
				 )
				)
			       )
			      ("p" "Projects"
			       ((todo "PROJECT")
				(stuck ""
				 ((org-agenda-sorting-strategy
				   '(alpha-up priority-down))
				  )
				 )
				)
			       )
			      ("c" "Work"
			       ((agenda ""
				 ((org-agenda-span 7)
				  (org-agenda-start-on-weekday 1))
				 )
				(todo "NEXT") (todo "WAITING") 
				(stuck))
			       ((org-agenda-files
				 (denote-directory-files-matching-regexp
				  "_cw.*_gtd")
				 )
				)
			       )
			      )
 org-log-into-drawer t
 org-agenda-skip-scheduled-if-done t
 org-agenda-files 
 '("/home/peter/Documents/notes/20220718T190010--notes-inbox__gtd.org" 
 "/home/peter/Documents/notes/20220719T125424--third-hemisphere-action-plan__gtd.org" 
 "/home/peter/Documents/notes/20230104T060726--lucid-manager-action-plan__gtd_lucidmanager.org" 
 "/home/peter/Documents/notes/20230104T193809--horizon-of-reason-action-plan__gtd.org" 
 "/home/peter/Documents/notes/20230115T083737--magic-perspectives-action-plan__gtd_magic.org" 
 "/home/peter/Documents/notes/20230801T092150--coliban-water-actions__cw_gtd.org" 
 "/home/peter/Documents/notes/20230821T094002--netherlands-trip-carnaval-expedition__gtd_nl.org" 
 "/home/peter/Documents/notes/20230826T154100--emacs-writing-studio__emacs_ews_gtd_productivity_project.org")
 org-persist-after-read-hook 
 '(org-element--cache-persist-after-read)
 org-export-before-parsing-hook '(org-attach-expand-links)
 org-cycle-tab-first-hook '(org-babel-hide-result-toggle-maybe
			    org-babel-header-arg-expand)
 org-startup-with-latex-preview t
 org-default-notes-file 
 "/home/peter/Documents/notes/20220718T190010--notes-inbox__gtd.org"
 org-archive-hook '(org-attach-archive-delete-maybe)
 org-cite-follow-processor 'citar
 org-odt-format-inlinetask-function 
 'org-odt-format-inlinetask-default-function
 org-ascii-format-drawer-function #[771 "\207" [] 4 "\n\n(fn NAME 
 CONTENTS WIDTH)"]
 org-cycle-hook '(org-cycle-hide-archived-subtrees
		  org-cycle-show-empty-lines
		  org-cycle-optimize-window-after-visibility-change
		  org-cycle-display-inline-images)
 org-export-with-broken-links t
 org-persist-before-read-hook 
 '(org-element--cache-persist-before-read)
 org-link-from-user-regexp "\\<peter@xps9315\\>\\|\\<Peter 
 Prevos\\>"
 org-image-actual-width '(450)
 org-mode-hook '(org-autolist-mode writegood-mode citar-capf-setup
		 #[0 "\301\211\207"
		   [imenu-create-index-function 
		   org-imenu-get-tree] 2]
		 org-fragtog-mode org-appear-mode 
		 global-org-modern-mode
		 mixed-pitch-mode
		 #[0 "\300\301\302\303\304$\207"
		   [add-hook change-major-mode-hook 
		   org-fold-show-all append
		    local]
		   5]
		 #[0 "\300\301\302\303\304$\207"
		   [add-hook change-major-mode-hook
		    org-babel-show-result-all append local]
		   5]
		 org-babel-result-hide-spec 
		 org-babel-hide-all-hashes)
 org-babel-load-languages '((emacs-lisp . t) (R . t) (python . t)
			    (julia . t) (shell . t) (latex . t))
 org-agenda-skip-deadline-if-done t
 org-cite-csl-styles-dir "~/Documents/library/csl/"
 org-modern-checkbox nil
 org-agenda-time-grid '((daily today require-timed)
			(800 1000 1200 1400 1600 1800 2000) 
			"......"
			"----------------")
 org-latex-format-drawer-function #[514 "\207" [] 3 "\n\n(fn _ 
 CONTENTS)"]
 org-ellipsis " ↲"
 org-latex-format-headline-function 
 'org-latex-format-headline-default-function
 org-confirm-shell-link-function 'yes-or-no-p
 org-html-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME 
 CONTENTS)"]
 outline-isearch-open-invisible-function 
 'outline-isearch-open-invisible
 org-export-with-todo-keywords nil
 org-stuck-projects '("/PROJECT" ("NEXT" "WAITING") nil
		      "SCHEDULED\\|DEADLINE")
 org-log-repeat nil
 org-startup-indented t
 org-fold-catch-invisible-edits 'error
 org-latex-classes '(("apa6"
		      "\\documentclass[a4paper, jou, 
		      11pt]{apa6}\n\\usepackage[nodoi]{apacite}\n\\usepackage[british]{babel}\n\\usepackage{inputenc}\n\\usepackage{amsmath}\n\\usepackage{graphicx}\n\\usepackage{csquotes}\n\\usepackage[hyphens]{url}\n\\usepackage[T1]{fontenc}\n\\usepackage{lmodern}\n\\usepackage{hyperref}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}"))
		     ("trade"
		      "\\documentclass[11pt, twoside]{memoir}\n 
		      \\setstocksize{9in}{6in}\n 
		      \\settrimmedsize{\\stockheight}{\\stockwidth}{*}\n 
		      \\setlrmarginsandblock{2cm}{2cm}{*} % Left 
		      and right margin\n 
		      \\setulmarginsandblock{2cm}{2cm}{*} % Upper 
		      and lower margin\n 
		      \\checkandfixthelayout\n 
		      \\setcounter{tocdepth}{0}\n 
		      \\OnehalfSpacing\n    \\usepackage{times}\n 
		      \\chapterstyle{bianchi}\n 
		      \\setsecheadstyle{\\normalfont \\raggedright 
		      \\textbf}\n 
		      \\setsubsecheadstyle{\\normalfont 
		      \\raggedright \\emph}\n 
		      \\setsubsubsecheadstyle{\\normalfont\\centering}\n 
		      \\usepackage[font={small, it}]{caption}\n 
		      \\usepackage{subcaption}\n 
		      \\captionsetup[subfigure]{justification=centering}\n 
		      \\usepackage{pdfpages}\n 
		      \\pagestyle{myheadings}\n 
		      \\usepackage{ccicons}\n 
		      \\usepackage{nicefrac}\n 
		      \\usepackage[authoryear]{natbib}\n 
		      \\bibliographystyle{apalike}\n 
		      \\usepackage{nohyperref}\n 
		      \\usepackage{tikz}\n 
		      \\usetikzlibrary{shapes.geometric, calc, 
		      knots}\n    \\usepackage{svg}"
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("crc"
		      "\\documentclass[krantz2]{krantz}\n 
		      \\usepackage{lmodern}\n 
		      \\usepackage[authoryear]{natbib}\n 
		      \\usepackage{nicefrac}\n 
		      \\usepackage[bf,singlelinecheck=off]{caption}\n 
		      \\captionsetup[table]{labelsep=space}\n 
		      \\captionsetup[figure]{labelsep=space}\n 
		      \\usepackage{Alegreya}\n 
		      \\usepackage[scale=.8]{sourcecodepro}\n 
		      \\usepackage[breaklines=true]{minted}\n 
		      \\usepackage{rotating}\n 
		      \\usepackage[notbib, 
		      nottoc,notlot,notlof]{tocbibind}\n 
		      \\usepackage{amsfonts, tikz, tikz-layers}\n 
		      \\usetikzlibrary{fadings, quotes, shapes, 
		      calc, decorations.markings}\n 
		      \\usetikzlibrary{patterns, shadows.blur}\n 
		      \\usetikzlibrary{shapes,shapes.geometric,positioning}\n 
		      \\usetikzlibrary{arrows, arrows.meta, 
		      backgrounds}\n        \\usepackage{imakeidx} 
		      \\makeindex[intoc]\n 
		      \\renewcommand{\\textfraction}{0.05}\n 
		      \\renewcommand{\\topfraction}{0.8}\n 
		      \\renewcommand{\\bottomfraction}{0.8}\n 
		      \\renewcommand{\\floatpagefraction}{0.75}\n 
		      \\renewcommand{\\eqref}[1]{(Equation 
		      \\ref{#1})}\n 
		      \\renewcommand{\\LaTeX}{LaTeX}"
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\paragraph*{%s}"))
		     ("magictrick"
		      "\\documentclass[11pt, a4paper, twocolumn, 
		      twoside]{article}\n\\usepackage{ccicons}\n\\usepackage{pdfpages}\n\\usepackage{times}\n\\usepackage{helvet}\n\\usepackage{geometry}\n\\geometry{a4paper, 
		      total={170mm,250mm}, left=20mm, top=30mm}\n% 
		      header 2008 x 332 
		      px\n\\usepackage{titlesec}\n\\titleformat{\\section}\n 
		      {\\bfseries}{\\thesection}{1em}{}\n\\titleformat{\\subsection}\n 
		      {\\itshape}{\\thesection}{1em}{}\n\\usepackage{fancyhdr}\n\\usepackage[font={small, 
		      it}, 
		      labelformat=empty]{caption}\n\\usepackage[hidelinks]{hyperref}\n\\pagestyle{fancy}\n\\renewcommand{\\headrulewidth}{0pt}\n\\renewcommand{\\footrulewidth}{0pt}\n\\setlength{\\parskip}{1em}\n\\renewcommand{\\baselinestretch}{1.1}\n\\setlength\\headheight{100.0pt}\n\\addtolength{\\textheight}{-100.0pt}\n\\fancyhead[LO]{\\Large{\\textsf{Magic 
		      Perspectives Presents}} 
		      \\includegraphics[width=\\textwidth]{header}}\n\\fancyhead[LE]{\\includegraphics[width=0.5\\textwidth]{header}}\n\\lfoot{Peter 
		      Prevos}\n\\rfoot{\\href{https://magicperspectives.net}{magicperspectives.net}}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}"))
		     ("ebook"
		      "\\documentclass[11pt, 
		      oneside]{memoir}\n\\setstocksize{9in}{6in}\n\\settrimmedsize{\\stockheight}{\\stockwidth}{*}\n\\setlrmarginsandblock{2cm}{2cm}{*} 
		      % Left and right 
		      margin\n\\setulmarginsandblock{2cm}{2cm}{*} 
		      % Upper and lower 
		      margin\n\\checkandfixthelayout\n\\usepackage{times}\n\\OnehalfSpacing\n\\usepackage[authoryear]{natbib}\n\\bibliographystyle{apalike}\n\\setlength{\\bibsep}{1pt}\n\\usepackage[raggedright]{sidecap}\n\\setsecheadstyle{\\normalfont 
		      \\raggedright 
		      \\textbf}\n\\setsubsecheadstyle{\\normalfont 
		      \\raggedright 
		      \\emph}\n\\usepackage{subcaption} 
		      \n\\usepackage[font={small, 
		      it}]{caption}\n\\captionsetup[subfigure]{justification=centering}\n\\usepackage{pdfpages}\n\\usepackage[unicode=true,\n 
		      bookmarks=true,bookmarksnumbered=false,bookmarksopen=true,\n 
		      bookmarksopenlevel=1, 
		      breaklinks=true,pdfborder={0 0 
		      0},backref=false,colorlinks=false,pdfborderstyle={/S/U/W 
		      .5}, allbordercolors={.8 .8 
		      .8}]{hyperref}\n\\pagestyle{myheadings}\n\\setcounter{tocdepth}{0}\n\\usepackage{ccicons}\n\\usepackage{nicefrac}\n"
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}"))
		     ("article"
		      "\\documentclass[10pt]{article}\n 
		      \\usepackage{tgpagella,eulervm}\n 
		      \\usepackage{nicefrac}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("article" "\\documentclass[11pt]{article}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("report" "\\documentclass[11pt]{report}"
		      ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}"))
		     ("book" "\\documentclass[11pt]{book}"
		      ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}"))
		     )
 org-odt-format-headline-function 
 'org-odt-format-headline-default-function
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-cycle-hide-block-startup t
 org-babel-tangle-lang-exts '(("latex" . "tex") ("julia" . "jl")
			      ("python" . "py") ("emacs-lisp" 
			      . "el")
			      ("elisp" . "el"))
 org-src-mode-hook '(org-src-babel-configure-edit-buffer
		     org-src-mode-configure-edit-buffer)
 org-confirm-elisp-link-function 'yes-or-no-p
 org-agenda-window-setup 'current-window
 org-latex-src-block-backend 'minted
 org-cycle-separator-lines 0
 org-cite-activate-processor 'citar
 org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAITING(w@/!)"
		      "PROJECT(p)" "GOAL(g)" "|" "DONE(d/!)"
		      "CANCELLED(c@/!)")
		     )
 org-latex-logfiles-extensions '("lof" "lot" "tex~" "aux" "idx" 
 "log" "out"
				 "toc" "nav" "snm" "vrb" "dvi" 
				 "fdb_latexmk"
				 "blg" "brf" "fls" "entoc" "ps" 
				 "spl" "bbl"
				 "tex" "bcf")
 org-structure-template-alist '(("ss" . "src shell\n") ("sr" 
 . "src R\n")
				("sp" . "src python\n")
				("se" . "src elisp\n")
				("a" . "export ascii") ("c" 
				. "center")
				("C" . "comment") ("e" 
				. "example")
				("E" . "export") ("h" . "export 
				html")
				("l" . "export latex") ("q" 
				. "quote")
				("s" . "src") ("v" . "verse"))
 org-speed-command-hook '(org-speed-command-activate
			  org-babel-speed-command-activate)
 org-html-format-inlinetask-function 
 'org-html-format-inlinetask-default-function
 org-ascii-format-inlinetask-function 
 'org-ascii-format-inlinetask-default
 org-modern-mode-hook '(org-modern-mode-set-explicitly)
 org-odt-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME 
 CONTENTS)"]
 org-confirm-babel-evaluate nil
 org-fold-core-isearch-open-function 
 'org-fold-core--isearch-reveal
 org-export-with-smart-quotes t
 org-modern-keyword nil
 org-cite-export-processors '((latex natbib "apalike2" 
 "authoryear")
			      (t csl "apa6.csl"))
 org-preview-latex-default-process 'dvisvgm
 org-latex-format-inlinetask-function 
 'org-latex-format-inlinetask-default-function
 org-persist-before-write-hook 
 '(org-element--cache-persist-before-write)
 org-tab-first-hook '(org-babel-hide-result-toggle-maybe
		      org-babel-header-arg-expand)
 org-export-with-toc nil
 org-link-shell-confirm-function 'yes-or-no-p
 org-agenda-finalize-hook '(org-modern-agenda)
 org-babel-pre-tangle-hook '(save-buffer)
 org-agenda-loop-over-headlines-in-active-region nil
 org-cite-global-bibliography 
 '("/home/peter/Documents/library/horizon-of-reason.bib" 
 "/home/peter/Documents/library/lucidmanager.bib" 
 "/home/peter/Documents/library/magic-science.bib" 
 "/home/peter/Documents/library/magic-tricks.bib" 
 "/home/peter/Documents/library/third-hemisphere.bib" 
 "/home/peter/Documents/library/zotero.bib" 
 "/home/peter/Documents/library/Kindle.json")
 org-occur-hook '(org-first-headline-recenter)
 org-capture-after-finalize-hook 
 '(denote-org-capture-delete-empty-file)
 org-export-with-drawers nil
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-odt-preferred-output-format "doc"
 org-link-parameters '(("attachment" :follow org-attach-follow 
 :complete
			org-attach-complete-link)
		       ("mu4e" :follow mu4e-org-open :store
			mu4e-org-store-link)
		       ("helpful" :store helpful--org-link-store)
		       ("eww" :follow org-eww-open :store 
		       org-eww-store-link)
		       ("rmail" :follow org-rmail-open :store
			org-rmail-store-link)
		       ("mhe" :follow org-mhe-open :store 
		       org-mhe-store-link)
		       ("irc" :follow org-irc-visit :store
			org-irc-store-link :export org-irc-export)
		       ("info" :follow org-info-open :export 
		       org-info-export
			:store org-info-store-link 
			:insert-description
			org-info-description-as-command)
		       ("gnus" :follow org-gnus-open :store
			org-gnus-store-link)
		       ("docview" :follow org-docview-open :export
			org-docview-export :store 
			org-docview-store-link)
		       ("bbdb" :follow org-bbdb-open :export 
		       org-bbdb-export
			:complete org-bbdb-complete-link :store
			org-bbdb-store-link)
		       ("w3m" :store org-w3m-store-link)
		       ("doi" :follow org-link-doi-open :export
			org-link-doi-export)
		       ("hugo" :complete
			(lambda nil
			 (concat "{{% ref "
			  (file-name-nondirectory (read-file-name 
			  "File: "))
			  " %}}")
			 )
			:follow org-hugo-followlink)
		       ("bibtex" :follow org-bibtex-open :store
			org-bibtex-store-link)
		       ("id" :follow org-id-open)
		       ("nov" :follow nov-org-link-follow :store
			nov-org-link-store)
		       ("denote" :follow denote-link-ol-follow 
		       :face
			denote-faces-link :complete 
			denote-link-ol-complete
			:store denote-link-ol-store :export
			denote-link-ol-export)
		       ("elfeed" :follow elfeed-link-open :store
			elfeed-link-store-link)
		       ("file+sys") ("file+emacs")
		       ("shell" :follow org-link--open-shell)
		       ("news" :follow
			#[514 "\301\300\302Q\"\207"
			  ["news" browse-url ":"] 6 "\n\n(fn URL 
			  ARG)"]
			)
		       ("mailto" :follow
			#[514 "\301\300\302Q\"\207"
			  ["mailto" browse-url ":"] 6 "\n\n(fn URL 
			  ARG)"]
			)
		       ("https" :follow
			#[514 "\301\300\302Q\"\207"
			  ["https" browse-url ":"] 6 "\n\n(fn URL 
			  ARG)"]
			)
		       ("http" :follow
			#[514 "\301\300\302Q\"\207"
			  ["http" browse-url ":"] 6 "\n\n(fn URL 
			  ARG)"]
			)
		       ("ftp" :follow
			#[514 "\301\300\302Q\"\207"
			  ["ftp" browse-url ":"] 6 "\n\n(fn URL 
			  ARG)"]
			)
		       ("help" :follow helpful--org-link-follow 
		       :store
			org-link--store-help)
		       ("file" :complete org-link-complete-file)
		       ("elisp" :follow org-link--open-elisp))
 org-html-format-headline-function 
 'org-html-format-headline-default-function
 org-agenda-start-with-follow-mode t
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-modern-table nil
 org-agenda-restore-windows-after-quit t
 org-agenda-remove-tags t
 org-num-format-function 'org-num-default-format
 org-agenda-include-diary t
 org-startup-with-inline-images t
 org-latex-pdf-process '("pdflatex -interaction nonstopmode 
 -output-directory %o %f" "bibtex %b" "pdflatex -shell-escape 
 -interaction nonstopmode -output-directory %o %f" "pdflatex 
 -shell-escape -interaction nonstopmode -output-directory %o %f")
 org-agenda-current-time-string "now - - - - - - - - - - - - - - - 
 - - - - - - - - - -"
 org-agenda-block-separator 61
 )
-- 
Dr Peter Prevos
---------------
peterprevos.com


^ permalink raw reply	[relevance 3%]

* Re: [patch] Fixes and improvements in org-latex-language-alist
  @ 2023-09-10 11:06  2%                         ` Juan Manuel Macías
  0 siblings, 0 replies; 200+ results
From: Juan Manuel Macías @ 2023-09-10 11:06 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode, Max Nikulin

[-- Attachment #1: Type: text/plain, Size: 863 bytes --]

Ihor Radchenko writes:

> It is not that complex, really. I suggested the above approach because:
> 1. It is easy to read - clearly, ,@de-plist and ,@de-plist are the same
>    thing.
> 2. If we ever need to change de-plist, we should only do it in a single
>    place.


The fact of avoiding copy/paste is already an advantage. New patch
attached with your suggestions. I have simply modified the variable name
a little. de-plist may seem a bit confusing, because there is also de-at
(Austrian German). I have set de-default-plist, since for babel and
polyglossia German (de) and German from Germany (de-de) are the default
variant. The same with the case of the Chinese (Chinese = Chinese
Simplified).

-- 
Juan Manuel Macías

https://juanmanuelmacias.com

https://lunotipia.juanmanuelmacias.com

https://gnutas.juanmanuelmacias.com


[-- Attachment #2: 0001-ox-latex.el-Fixes-and-improvements-in-org-latex-lang.patch --]
[-- Type: text/x-patch, Size: 22021 bytes --]

From 73057fc06990f861468c397c94b7076d025acbc8 Mon Sep 17 00:00:00 2001
From: Juan Manuel Macias <maciaschain@posteo.net>
Date: Fri, 8 Sep 2023 19:33:25 +0200
Subject: [PATCH] ox-latex.el: Fixes and improvements in
 `org-latex-language-alist'.

* (org-latex-language-alist): Fix a language code (`de-de') removed
when `org-latex-babel-language-alist' and
`org-latex-polyglossia-language-alist' were merged.  To allow language
codes that can have a similar translation in `babel' or `polyglossia'
now in each element of `org-latex-language-alist' car can also be a
list of language codes.  New admitted properties: `:babel-ini-alt',
`:script' and `:script-tag'.  Add language code for ancient Greek.
Fix Afrikaans (was previously removed).  New languages: Chinese
Simplified and Traditional.  Correction of some typos, errors and
inaccuracies.  `let' bindings suggested by Ihor Radchenko.

* (org-latex-guess-babel-language): Some necessary modifications.
---
 lisp/ox-latex.el | 197 ++++++++++++++++++++++++++---------------------
 1 file changed, 109 insertions(+), 88 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 241ef603a..14105c7cc 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -177,94 +177,105 @@
 ;;; Internal Variables
 
 (defconst org-latex-language-alist
-  '(("am" :babel-ini-only "amharic" :polyglossia "amharic" :lang-name "Amharic")
-    ("ar" :babel "arabic" :polyglossia "arabic" :lang-name "Arabic")
-    ("ast" :babel-ini-only "asturian" :polyglossia "asturian" :lang-name "Asturian")
-    ("bg"  :babel "bulgarian" :polyglossia "bulgarian" :lang-name "Bulgarian")
-    ("bn"  :babel-ini-only "bengali" :polyglossia "bengali" :lang-name "Bengali")
-    ("bo"  :babel-ini-only "tibetan" :polyglossia "tibetan" :lang-name "Tibetan")
-    ("br"  :babel "breton" :polyglossia "breton" :lang-name "Breton")
-    ("ca"  :babel "catalan" :polyglossia "catalan" :lang-name "Catalan")
-    ("cop"  :babel-ini-only "coptic" :polyglossia "coptic" :lang-name "Coptic")
-    ("cs"  :babel "czech" :polyglossia "czech" :lang-name "Czech")
-    ("cy"  :babel "welsh" :polyglossia "welsh" :lang-name "Welsh")
-    ("da"  :babel "danish" :polyglossia "danish" :lang-name "Danish")
-    ("de"  :babel "ngerman" :polyglossia "german" :polyglossia-variant "german" :lang-name "German")
-    ("de-at"  :babel "naustrian" :polyglossia "german" :polyglossia-variant "austrian" :lang-name "German")
-    ("dsb"  :babel "lsorbian" :polyglossia "sorbian" :polyglossia-variant "lower" :lang-name "Lower Sorbian")
-    ("dv"  :babel-ini-only "divehi" :polyglossia "divehi" :lang-name "Divehi")
-    ("el"  :babel "greek" :polyglossia "greek" :lang-name "Greek")
-    ("el-polyton"  :babel "polutonikogreek" :polyglossia "greek" :polyglossia-variant "polytonic" :lang-name "Polytonic Greek")
-    ("en"  :babel "american" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English")
-    ("en-au"  :babel "australian" :polyglossia "english" :polyglossia-variant "australian" :lang-name "English")
-    ("en-gb"  :babel "british" :polyglossia "english" :polyglossia-variant "uk" :lang-name "English")
-    ("en-nz"  :babel "newzealand" :polyglossia "english" :polyglossia-variant "newzealand" :lang-name "English")
-    ("en-us"  :babel "american" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English")
-    ("eo"  :babel "esperanto" :polyglossia "esperanto" :lang-name "Esperanto")
-    ("es"  :babel "spanish" :polyglossia "spanish" :lang-name "Spanish")
-    ("es-mx"  :babel "spanishmx" :polyglossia "spanish" :polyglossia-variant "mexican" :lang-name "Spanish")
-    ("et"  :babel "estonian" :polyglossia "estonian" :lang-name "Estonian")
-    ("eu"  :babel "basque" :polyglossia "basque" :lang-name "Basque")
-    ("fa"  :babel "farsi" :polyglossia "farsi" :lang-name "Farsi")
-    ("fi"  :babel "finnish" :polyglossia "finnish" :lang-name "Finnish")
-    ("fr"  :babel "french" :polyglossia "french" :lang-name "French")
-    ("fr-ca"  :babel "canadien" :polyglossia "french" :polyglossia-variant "canadian" :lang-name "French")
-    ("fur"  :babel "friulan" :polyglossia "friulan" :lang-name "Friulian")
-    ("ga"  :babel "irish" :polyglossia "irish" :lang-name "Irish")
-    ("gd"  :babel "scottish" :polyglossia "scottish" :lang-name "Scottish Gaelic")
-    ("gl"  :babel "galician" :polyglossia "galician" :lang-name "Galician")
-    ("he"  :babel "hebrew" :polyglossia "hebrew" :lang-name "Hebrew")
-    ("hi"  :babel "hindi" :polyglossia "hindi" :lang-name "Hindi")
-    ("hr"  :babel "croatian" :polyglossia "croatian" :lang-name "Croatian")
-    ("hsb"  :babel "uppersorbian" :polyglossia "sorbian" :polyglossia-variant "upper" :lang-name "Upper Sorbian")
-    ("hu"  :babel "magyar" :polyglossia "magyar" :lang-name "Magyar")
-    ("hy"  :babel-ini-only "armenian" :polyglossia "armenian" :lang-name "Armenian")
-    ("ia"  :babel "interlingua" :polyglossia "interlingua" :lang-name "Interlingua")
-    ("id"  :babel-ini-only "bahasai" :polyglossia "bahasai" :lang-name "Bahasai")
-    ("is"  :babel "icelandic" :polyglossia "icelandic" :lang-name "Icelandic")
-    ("it"  :babel "italian" :polyglossia "italian" :lang-name "Italian")
-    ("kn"  :babel-ini-only "kannada" :polyglossia "kannada" :lang-name "Kannada")
-    ("la"  :babel "latin" :polyglossia "latin" :lang-name "Latin")
-    ("la-classic"  :babel "classiclatin" :polyglossia "latin" :polyglossia-variant "classic" :lang-name "Classic Latin")
-    ("la-medieval"  :babel "medievallatin" :polyglossia "latin" :polyglossia-variant "medieval" :lang-name "Medieval Latin")
-    ("la-ecclesiastic"  :babel "ecclesiasticlatin" :polyglossia "latin" :polyglossia-variant "ecclesiastic" :lang-name "Ecclesiastic Latin")
-    ("lo"  :babel-ini-only "lao" :polyglossia "lao" :lang-name "Lao")
-    ("lt"  :babel "lithuanian" :polyglossia "lithuanian" :lang-name "Lithuanian")
-    ("lv"  :babel "latvian" :polyglossia "latvian" :lang-name "Latvian")
-    ("ml"  :babel-ini-only "malayalam" :polyglossia "malayalam" :lang-name "Malayalam")
-    ("mr"  :babel-ini-only "maranthi" :polyglossia "maranthi" :lang-name "Maranthi")
-    ("nb"  :babel "norsk" :polyglossia "norwegian" :polyglossia-variant "bokmal" :lang-name "Norwegian Bokmål")
-    ("nl"  :babel "dutch" :polyglossia "dutch" :lang-name "Dutch")
-    ("nn"  :babel "nynorsk" :polyglossia "norwegian" :polyglossia-variant "nynorsk" :lang-name "Norwegian Nynorsk")
-    ("no"  :babel "norsk" :polyglossia "norsk" :lang-name "Norwegian")
-    ("oc"  :babel "occitan" :polyglossia "occitan" :lang-name "Occitan")
-    ("pl"  :babel "polish" :polyglossia "polish" :lang-name "Polish")
-    ("pms"  :babel "piedmontese" :polyglossia "piedmontese" :lang-name "Piedmontese")
-    ("pt"  :babel "portuges" :polyglossia "portuges" :lang-name "Portuges")
-    ("pt-br"  :babel "brazilian" :polyglossia "brazilian" :lang-name "Portuges")
-    ("rm"  :babel-ini-only "romansh" :polyglossia "romansh" :lang-name "Romansh")
-    ("ro"  :babel "romanian" :polyglossia "romanian" :lang-name "Romanian")
-    ("ru"  :babel "russian" :polyglossia "russian" :lang-name "Russian")
-    ("sa"  :babel-ini-only "sanskrit" :polyglossia "sanskrit" :lang-name "Sanskrit")
-    ("sk"  :babel "slovak" :polyglossia "slovak" :lang-name "Slovak")
-    ("sl"  :babel "slovene" :polyglossia "slovene" :lang-name "Slovene")
-    ("sq"  :babel "albanian" :polyglossia "albanian" :lang-name "Albanian")
-    ("sr"  :babel "serbian" :polyglossia "serbian" :lang-name "Serbian")
-    ("sv"  :babel "swedish" :polyglossia "swedish" :lang-name "Swedish")
-    ("syr"  :babel-ini-only "syriac" :polyglossia "syriac" :lang-name "Syriac")
-    ("ta"  :babel-ini-only "tamil" :polyglossia "tamil" :lang-name "Tamil")
-    ("te"  :babel-ini-only "telugu" :polyglossia "telugu" :lang-name "Telugu")
-    ("th"  :babel "thai" :polyglossia "thai" :lang-name "Thai")
-    ("tk"  :babel "turkmen" :polyglossia "turkmen" :lang-name "Turkmen")
-    ("tr"  :babel "turkish" :polyglossia "turkish" :lang-name "Turkish")
-    ("uk"  :babel "ukrainian" :polyglossia "ukrainian" :lang-name "Ukrainian")
-    ("ur"  :babel-ini-only "urdu" :polyglossia "urdu" :lang-name "Urdu")
-    ("vi"  :babel "vietnamese" :polyglossia "vietnamese" :lang-name "Vietnamese"))
+  (let ((de-default-plist '(:babel "ngerman" :babel-ini-alt "german" :polyglossia "german" :polyglossia-variant "german" :lang-name "German" :script "latin" :script-tag "latn"))
+        (zh-default-plist '(:babel-ini-only "chinese" :polyglossia "chinese" :polyglossia-variant "simplified" :lang-name "Chinese Simplified" :script "hans" :script-tag "hans")))
+    `(("af" :babel "afrikaans" :polyglossia "afrikaans" :lang-name "Afrikaans" :script "latin" :script-tag "latn")
+      ("am" :babel-ini-only "amharic" :polyglossia "amharic" :lang-name "Amharic" :script "ethiopic" :script-tag "ethi")
+      ("ar" :babel-ini-only "arabic" :polyglossia "arabic" :lang-name "Arabic" :script "arabic" :script-tag "arab")
+      ("ast" :babel-ini-only "asturian" :polyglossia "asturian" :lang-name "Asturian" :script "latin" :script-tag "latn")
+      ("bg"  :babel "bulgarian" :polyglossia "bulgarian" :lang-name "Bulgarian" :script "cyrillic" :script-tag "cyrl")
+      ("bn"  :babel-ini-only "bengali" :polyglossia "bengali" :lang-name "Bengali" :script "bengali" :script-tag: "beng")
+      ("bo"  :babel-ini-only "tibetan" :polyglossia "tibetan" :lang-name "Tibetan" :script "tibetan" :script-tag "tib")
+      ("br"  :babel "breton" :polyglossia "breton" :lang-name "Breton" :script "latin" :script-tag "latn")
+      ("ca"  :babel "catalan" :polyglossia "catalan" :lang-name "Catalan" :script "latin" :script-tag "latn")
+      ("cop"  :babel-ini-only "coptic" :polyglossia "coptic" :lang-name "Coptic" :script "coptic" :script-tag "copt")
+      ("cs"  :babel "czech" :polyglossia "czech" :lang-name "Czech" :script "latin" :script-tag "latn")
+      ("cy"  :babel "welsh" :polyglossia "welsh" :lang-name "Welsh" :script "latin" :script-tag "latn")
+      ("da"  :babel "danish" :polyglossia "danish" :lang-name "Danish" :script "latin" :script-tag "latn")
+      ("de" ,@de-default-plist)
+      ("de-de" ,@de-default-plist)
+      ("de-at" :babel "naustrian" :babel-ini-alt "german-austria" :polyglossia "german" :polyglossia-variant "austrian" :lang-name "German" :script "latin" :script-tag "latn")
+      ("dsb" :babel "lowersorbian" :babel-ini-alt "lsorbian" :polyglossia "sorbian" :polyglossia-variant "lower" :lang-name "Lower Sorbian" :script "latin" :script-tag "latn")
+      ("dv" :polyglossia "divehi" :lang-name "Dhivehi" :script "latin" :script-tag "latn")
+      ("el" :babel "greek" :polyglossia "greek" :lang-name "Greek" :script "greek" :script-tag "grek")
+      ("el-polyton"  :babel "polutonikogreek" :babel-ini-alt "polytonicgreek" :polyglossia "greek" :polyglossia-variant "polytonic" :lang-name "Polytonic Greek" :script "greek" :script-tag "grek")
+      ("grc" :babel "greek.ancient" :babel-ini-alt "ancientgreek" :polyglossia "greek" :polyglossia-variant "ancient" :lang-name "Ancient Greek" :script "greek" :script-tag "grek")
+      ("en" :babel "english" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English" :script "latin" :script-tag "latn")
+      ("en-au" :babel "australian" :polyglossia "english" :polyglossia-variant "australian" :lang-name "English" :script "latin" :script-tag "latn")
+      ("en-ca" :babel "canadian" :polyglossia "english" :polyglossia-variant "canadian" :lang-name "English" :script "latin" :script-tag "latn")
+      ("en-gb" :babel "british" :polyglossia "english" :polyglossia-variant "uk" :lang-name "English" :script "latin" :script-tag "latn")
+      ("en-nz" :babel "newzealand" :polyglossia "english" :polyglossia-variant "newzealand" :lang-name "English" :script "latin" :script-tag "latn")
+      ("en-us" :babel "american" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English" :script "latin" :script-tag "latn")
+      ("eo" :babel "esperanto" :polyglossia "esperanto" :lang-name "Esperanto" :script "latin" :script-tag "latn")
+      ("es" :babel "spanish" :polyglossia "spanish" :lang-name "Spanish" :script "latin" :script-tag "latn")
+      ("es-mx" :babel "spanishmx" :polyglossia "spanish" :polyglossia-variant "mexican" :lang-name "Spanish" :script "latin" :script-tag "latn")
+      ("et" :babel "estonian" :polyglossia "estonian" :lang-name "Estonian" :script "latin" :script-tag "latn")
+      ("eu" :babel "basque" :polyglossia "basque" :lang-name "Basque" :script "latin" :script-tag "latn")
+      ("fa" :babel "persian" :polyglossia "persian" :lang-name "Persian" :script "arabic" :script-tag "arab")
+      ("fi" :babel "finnish" :polyglossia "finnish" :lang-name "Finnish" :script "latin" :script-tag "latn")
+      ("fr" :babel "french" :polyglossia "french" :lang-name "French" :script "latin" :script-tag "latn")
+      ("fr-ca" :babel "canadien" :babel-ini-alt "canadian" :polyglossia "french" :polyglossia-variant "canadian" :lang-name "French" :script "latin" :script-tag "latn")
+      ("fur" :babel "friulian" :polyglossia "friulian" :lang-name "Friulian" :script "latin" :script-tag "latn")
+      ("ga" :babel "irish" :polyglossia "gaelic" :polyglossia-variant "irish" :lang-name "Irish Gaelic" :script "latin" :script-tag "latn")
+      ("gd" :babel "scottish" :polyglossia "gaelic" :polyglossia-variant "scottish" :lang-name "Scottish Gaelic" :script "latin" :script-tag "latn")
+      ("gl" :babel "galician" :polyglossia "galician" :lang-name "Galician" :script "latin" :script-tag "latn")
+      ("he" :babel "hebrew" :polyglossia "hebrew" :lang-name "Hebrew" :script "hebrew" :script-tag "hebr")
+      ("hi" :babel "hindi" :polyglossia "hindi" :lang-name "Hindi" :script "devanagari" :script-tag "deva")
+      ("hr" :babel "croatian" :polyglossia "croatian" :lang-name "Croatian" :script "latin" :script-tag "latn")
+      ("hsb" :babel "uppersorbian" :polyglossia "sorbian" :polyglossia-variant "upper" :lang-name "Upper Sorbian" :script "latin" :script-tag "latn")
+      ("hu" :babel "magyar" :polyglossia "magyar" :lang-name "Magyar" :script "latin" :script-tag "latn")
+      ("hy" :babel-ini-only "armenian" :polyglossia "armenian" :lang-name "Armenian" :script "armenian" :script-tag "armn")
+      ("ia" :babel "interlingua" :polyglossia "interlingua" :lang-name "Interlingua" :script "latin" :script-tag "latn")
+      ("id" :babel "indonesian" :polyglossia "malay" :polyglossia-variant "indonesian" :lang-name "Indonesian" :script "latin" :script-tag "latn")
+      ("is" :babel "icelandic" :polyglossia "icelandic" :lang-name "Icelandic" :script "latin" :script-tag "latn")
+      ("it" :babel "italian" :polyglossia "italian" :lang-name "Italian" :script "latin" :script-tag "latn")
+      ("kn" :babel-ini-only "kannada" :polyglossia "kannada" :lang-name "Kannada" :script "kannada" :script-tag "knda")
+      ("la" :babel "latin" :polyglossia "latin" :lang-name "Latin" :script "latin" :script-tag "latn")
+      ("la-classic"  :babel "classiclatin" :polyglossia "latin" :polyglossia-variant "classic" :lang-name "Classic Latin" :script "latin" :script-tag "latn")
+      ("la-medieval"  :babel "medievallatin" :polyglossia "latin" :polyglossia-variant "medieval" :lang-name "Medieval Latin" :script "latin" :script-tag "latn")
+      ("la-ecclesiastic"  :babel "ecclesiasticlatin" :polyglossia "latin" :polyglossia-variant "ecclesiastic" :lang-name "Ecclesiastic Latin" :script "latin" :script-tag "latn")
+      ("lo" :babel-ini-only "lao" :polyglossia "lao" :lang-name "Lao" :script "lao" :script-tag "lao")
+      ("lt" :babel "lithuanian" :polyglossia "lithuanian" :lang-name "Lithuanian" :script "latin" :script-tag "latn")
+      ("lv" :babel "latvian" :polyglossia "latvian" :lang-name "Latvian" :script "latin" :script-tag "latn")
+      ("ml" :babel-ini-only "malayalam" :polyglossia "malayalam" :lang-name "Malayalam" :script "malayalam" :script-tag "mlym")
+      ("mr" :babel-ini-only "marathi" :polyglossia "marathi" :lang-name "Marathi" :script "devanagari" :script-tag "deva")
+      ("ms" :babel "malay" :polyglossia "malay" :polyglossia-variant "malaysian" :lang-name "Malay" :script "latin" :script-tag "latn")
+      ("nb" :babel "norsk" :polyglossia "norwegian" :polyglossia-variant "bokmal" :lang-name "Norwegian Bokmål" :script "latin" :script-tag "latn")
+      ("nl" :babel "dutch" :polyglossia "dutch" :lang-name "Dutch" :script "latin" :script-tag "latn")
+      ("nn" :babel "nynorsk" :polyglossia "norwegian" :polyglossia-variant "nynorsk" :lang-name "Norwegian Nynorsk" :script "latin" :script-tag "latn")
+      ("no" :babel "norsk" :polyglossia "norsk" :lang-name "Norwegian" :script "latin" :script-tag "latn")
+      ("oc" :babel "occitan" :polyglossia "occitan" :lang-name "Occitan" :script "latin" :script-tag "latn")
+      ("pl" :babel "polish" :polyglossia "polish" :lang-name "Polish" :script "latin" :script-tag "latn")
+      ("pms" :babel "piedmontese" :polyglossia "piedmontese" :lang-name "Piedmontese" :script "latin" :script-tag "latn")
+      ("pt"  :babel "portuges" :polyglossia "portuges" :lang-name "Portuges" :script "latin" :script-tag "latn")
+      ("pt-br" :babel "brazilian" :polyglossia "brazilian" :lang-name "Portuges" :script "latin" :script-tag "latn")
+      ("rm" :babel-ini-only "romansh" :polyglossia "romansh" :lang-name "Romansh" :script "latin" :script-tag "latn")
+      ("ro" :babel "romanian" :polyglossia "romanian" :lang-name "Romanian" :script "latin" :script-tag "latn")
+      ("ru" :babel "russian" :polyglossia "russian" :lang-name "Russian" :script "cyrillic" :script-tag "cyrl")
+      ("sa" :babel-ini-only "sanskrit" :polyglossia "sanskrit" :lang-name "Sanskrit" :script "devanagari" :script-tag "deva")
+      ("sk" :babel "slovak" :polyglossia "slovak" :lang-name "Slovak" :script "latin" :script-tag "latn")
+      ("sl" :babel "slovene" :polyglossia "slovene" :lang-name "Slovene" :script "latin" :script-tag "latn")
+      ("sq" :babel "albanian" :polyglossia "albanian" :lang-name "Albanian" :script "latin" :script-tag "latn")
+      ("sr" :babel "serbian" :polyglossia "serbian" :lang-name "Serbian" :script "latin" :script-tag "latn")
+      ("sr-cyrl" :babel-ini-only "serbian-cyrl" :polyglossia "serbian" :lang-name "Serbian" :script "cyrillic" :script-tag "cyrl")
+      ("sr-latn" :babel-ini-only "serbian-latin" :polyglossia "serbian" :lang-name "Serbian" :script "latin" :script-tag "latn")
+      ("sv"  :babel "swedish" :polyglossia "swedish" :lang-name "Swedish" :script "latin" :script-tag "latn")
+      ("syr" :babel-ini-only "syriac" :polyglossia "syriac" :lang-name "Syriac" :script "syriac" :script-tag "syrc")
+      ("ta" :babel-ini-only "tamil" :polyglossia "tamil" :lang-name "Tamil" :script "tamil" :script-tag "taml")
+      ("te" :babel-ini-only "telugu" :polyglossia "telugu" :lang-name "Telugu" :script "telugu" :script-tag "telu")
+      ("th" :babel "thai" :polyglossia "thai" :lang-name "Thai" :script "thai" :script-tag "thai")
+      ("tk" :babel "turkmen" :polyglossia "turkmen" :lang-name "Turkmen" :script "latin" :script-tag "latn")
+      ("tr" :babel "turkish" :polyglossia "turkish" :lang-name "Turkish" :script "latin" :script-tag "latn")
+      ("uk" :babel "ukrainian" :polyglossia "ukrainian" :lang-name "Ukrainian" :script "cyrillic" :script-tag "cyrl")
+      ("ur" :babel-ini-only "urdu" :polyglossia "urdu" :lang-name "Urdu" :script "arabic" :script-tag "arab")
+      ("vi" :babel "vietnamese" :polyglossia "vietnamese" :lang-name "Vietnamese" :script "latin" :script-tag "latn")
+      ("zh" ,@zh-default-plist)
+      ("zh-cn" ,@zh-default-plist)
+      ("zh-tw" :babel-ini-only "chinese-traditional" :polyglossia "chinese" :polyglossia-variant "traditional" :lang-name "Chinese Traditional" :script "hant" :script-tag "hant")))
   "Alist between language code and its properties for LaTeX export.
 
-In each element of the list car is always the code of the
-language and cdr is a property list.  Valid keywords for this
-list can be:
+In each element of the list car is always the language code and
+cdr is a property list.  Valid keywords for this list can be:
 
 - `:babel' the name of the language loaded by the Babel LaTeX package
 
@@ -275,9 +286,17 @@ list can be:
  exclusively through the new ini files method.  See
  `http://mirrors.ctan.org/macros/latex/required/babel/base/babel.pdf'
 
+- `:babel-ini-alt' an alternative language name when it is loaded
+  using ini files
+
 - `:polyglossia-variant' the language variant loaded by Polyglossia
 
-- `:lang-name' the actual name of the language.")
+- `:lang-name' the actual name of the language
+
+- `:script' the script name
+
+- `:script-tag' the script otf tag.")
+
 
 (defconst org-latex-line-break-safe "\\\\[0pt]"
   "Linebreak protecting the following [...].
@@ -1660,6 +1679,7 @@ Return the new header."
 		 (assoc language-code org-latex-language-alist)))
 	 (language (plist-get plist :babel))
 	 (language-ini-only (plist-get plist :babel-ini-only))
+         (language-ini-alt (plist-get plist :babel-ini-alt))
 	 ;; If no language is set, or Babel package is not loaded, or
 	 ;; LANGUAGE keyword value is a language served by Babel
 	 ;; exclusively through ini files, return HEADER as-is.
@@ -1691,7 +1711,8 @@ Return the new header."
 	    (replace-regexp-in-string (format
 				       "\\(\\\\babelprovide\\[.*\\]\\)\\({\\)%s}" prov)
 				      (format "\\1\\2%s}"
-					      (or language language-ini-only))
+					      (if language-ini-alt language-ini-alt
+                                                (or language language-ini-only)))
 				      header t)
 	  header)))))
 
-- 
2.42.0


^ permalink raw reply related	[relevance 2%]

* [patch] Fixes and improvements in org-latex-language-alist (was: ox-latex language handling in Org-9.5 vs 9.6)
  @ 2023-09-08 19:02  2%             ` Juan Manuel Macías
    0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2023-09-08 19:02 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: Max Nikulin, Ihor Radchenko

[-- Attachment #1: Type: text/plain, Size: 666 bytes --]

I think that with this patch the possible regressions are removed. I
took the opportunity to add some improvements (the :babel-ini-alt,
:script and :script-tag properties) and correct some errors and typos.

I don't know if it's a valid path to allow the car of each element to
also be a list of languages codes, but I couldn't think of a better
solution for the "de"/"de-de" cases. A similar case is in Chinese
Simplified (new language added), where the possible language codes are
zh and zh-cn, if I'm not wrong.

--
Juan Manuel Macías

https://juanmanuelmacias.com

https://lunotipia.juanmanuelmacias.com

https://gnutas.juanmanuelmacias.com


[-- Attachment #2: 0001-ox-latex.el-Fixes-and-improvements-in-org-latex-lang.patch --]
[-- Type: text/x-patch, Size: 22948 bytes --]

From 52f17bc841241562a52e91159cb1531dbe5684e1 Mon Sep 17 00:00:00 2001
From: Juan Manuel Macias <maciaschain@posteo.net>
Date: Fri, 8 Sep 2023 19:33:25 +0200
Subject: [PATCH] ox-latex.el: Fixes and improvements in
 `org-latex-language-alist'.

* (org-latex-language-alist): Fix a language code (`de-de') removed
when `org-latex-babel-language-alist' and
`org-latex-polyglossia-language-alist' were merged.  To allow language
codes that can have a similar translation in `babel' or `polyglossia'
now in each element of `org-latex-language-alist' car can also be a
list of language codes.  New admitted properties: `:babel-ini-alt',
`:script' and `:script-tag'.  Add language code for ancient Greek.
Fix Afrikaans (was previously removed).  New languages: Chinese
Simplified and Traditional.  Correction of some typos, errors and
inaccuracies.

* (org-latex-guess-babel-language): Some necessary modifications.

* (org-latex-guess-polyglossia-language): Some necessary modifications.
---
 lisp/ox-latex.el | 208 +++++++++++++++++++++++++++--------------------
 1 file changed, 118 insertions(+), 90 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 241ef603a..d6790ea27 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -177,94 +177,102 @@
 ;;; Internal Variables
 
 (defconst org-latex-language-alist
-  '(("am" :babel-ini-only "amharic" :polyglossia "amharic" :lang-name "Amharic")
-    ("ar" :babel "arabic" :polyglossia "arabic" :lang-name "Arabic")
-    ("ast" :babel-ini-only "asturian" :polyglossia "asturian" :lang-name "Asturian")
-    ("bg"  :babel "bulgarian" :polyglossia "bulgarian" :lang-name "Bulgarian")
-    ("bn"  :babel-ini-only "bengali" :polyglossia "bengali" :lang-name "Bengali")
-    ("bo"  :babel-ini-only "tibetan" :polyglossia "tibetan" :lang-name "Tibetan")
-    ("br"  :babel "breton" :polyglossia "breton" :lang-name "Breton")
-    ("ca"  :babel "catalan" :polyglossia "catalan" :lang-name "Catalan")
-    ("cop"  :babel-ini-only "coptic" :polyglossia "coptic" :lang-name "Coptic")
-    ("cs"  :babel "czech" :polyglossia "czech" :lang-name "Czech")
-    ("cy"  :babel "welsh" :polyglossia "welsh" :lang-name "Welsh")
-    ("da"  :babel "danish" :polyglossia "danish" :lang-name "Danish")
-    ("de"  :babel "ngerman" :polyglossia "german" :polyglossia-variant "german" :lang-name "German")
-    ("de-at"  :babel "naustrian" :polyglossia "german" :polyglossia-variant "austrian" :lang-name "German")
-    ("dsb"  :babel "lsorbian" :polyglossia "sorbian" :polyglossia-variant "lower" :lang-name "Lower Sorbian")
-    ("dv"  :babel-ini-only "divehi" :polyglossia "divehi" :lang-name "Divehi")
-    ("el"  :babel "greek" :polyglossia "greek" :lang-name "Greek")
-    ("el-polyton"  :babel "polutonikogreek" :polyglossia "greek" :polyglossia-variant "polytonic" :lang-name "Polytonic Greek")
-    ("en"  :babel "american" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English")
-    ("en-au"  :babel "australian" :polyglossia "english" :polyglossia-variant "australian" :lang-name "English")
-    ("en-gb"  :babel "british" :polyglossia "english" :polyglossia-variant "uk" :lang-name "English")
-    ("en-nz"  :babel "newzealand" :polyglossia "english" :polyglossia-variant "newzealand" :lang-name "English")
-    ("en-us"  :babel "american" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English")
-    ("eo"  :babel "esperanto" :polyglossia "esperanto" :lang-name "Esperanto")
-    ("es"  :babel "spanish" :polyglossia "spanish" :lang-name "Spanish")
-    ("es-mx"  :babel "spanishmx" :polyglossia "spanish" :polyglossia-variant "mexican" :lang-name "Spanish")
-    ("et"  :babel "estonian" :polyglossia "estonian" :lang-name "Estonian")
-    ("eu"  :babel "basque" :polyglossia "basque" :lang-name "Basque")
-    ("fa"  :babel "farsi" :polyglossia "farsi" :lang-name "Farsi")
-    ("fi"  :babel "finnish" :polyglossia "finnish" :lang-name "Finnish")
-    ("fr"  :babel "french" :polyglossia "french" :lang-name "French")
-    ("fr-ca"  :babel "canadien" :polyglossia "french" :polyglossia-variant "canadian" :lang-name "French")
-    ("fur"  :babel "friulan" :polyglossia "friulan" :lang-name "Friulian")
-    ("ga"  :babel "irish" :polyglossia "irish" :lang-name "Irish")
-    ("gd"  :babel "scottish" :polyglossia "scottish" :lang-name "Scottish Gaelic")
-    ("gl"  :babel "galician" :polyglossia "galician" :lang-name "Galician")
-    ("he"  :babel "hebrew" :polyglossia "hebrew" :lang-name "Hebrew")
-    ("hi"  :babel "hindi" :polyglossia "hindi" :lang-name "Hindi")
-    ("hr"  :babel "croatian" :polyglossia "croatian" :lang-name "Croatian")
-    ("hsb"  :babel "uppersorbian" :polyglossia "sorbian" :polyglossia-variant "upper" :lang-name "Upper Sorbian")
-    ("hu"  :babel "magyar" :polyglossia "magyar" :lang-name "Magyar")
-    ("hy"  :babel-ini-only "armenian" :polyglossia "armenian" :lang-name "Armenian")
-    ("ia"  :babel "interlingua" :polyglossia "interlingua" :lang-name "Interlingua")
-    ("id"  :babel-ini-only "bahasai" :polyglossia "bahasai" :lang-name "Bahasai")
-    ("is"  :babel "icelandic" :polyglossia "icelandic" :lang-name "Icelandic")
-    ("it"  :babel "italian" :polyglossia "italian" :lang-name "Italian")
-    ("kn"  :babel-ini-only "kannada" :polyglossia "kannada" :lang-name "Kannada")
-    ("la"  :babel "latin" :polyglossia "latin" :lang-name "Latin")
-    ("la-classic"  :babel "classiclatin" :polyglossia "latin" :polyglossia-variant "classic" :lang-name "Classic Latin")
-    ("la-medieval"  :babel "medievallatin" :polyglossia "latin" :polyglossia-variant "medieval" :lang-name "Medieval Latin")
-    ("la-ecclesiastic"  :babel "ecclesiasticlatin" :polyglossia "latin" :polyglossia-variant "ecclesiastic" :lang-name "Ecclesiastic Latin")
-    ("lo"  :babel-ini-only "lao" :polyglossia "lao" :lang-name "Lao")
-    ("lt"  :babel "lithuanian" :polyglossia "lithuanian" :lang-name "Lithuanian")
-    ("lv"  :babel "latvian" :polyglossia "latvian" :lang-name "Latvian")
-    ("ml"  :babel-ini-only "malayalam" :polyglossia "malayalam" :lang-name "Malayalam")
-    ("mr"  :babel-ini-only "maranthi" :polyglossia "maranthi" :lang-name "Maranthi")
-    ("nb"  :babel "norsk" :polyglossia "norwegian" :polyglossia-variant "bokmal" :lang-name "Norwegian Bokmål")
-    ("nl"  :babel "dutch" :polyglossia "dutch" :lang-name "Dutch")
-    ("nn"  :babel "nynorsk" :polyglossia "norwegian" :polyglossia-variant "nynorsk" :lang-name "Norwegian Nynorsk")
-    ("no"  :babel "norsk" :polyglossia "norsk" :lang-name "Norwegian")
-    ("oc"  :babel "occitan" :polyglossia "occitan" :lang-name "Occitan")
-    ("pl"  :babel "polish" :polyglossia "polish" :lang-name "Polish")
-    ("pms"  :babel "piedmontese" :polyglossia "piedmontese" :lang-name "Piedmontese")
-    ("pt"  :babel "portuges" :polyglossia "portuges" :lang-name "Portuges")
-    ("pt-br"  :babel "brazilian" :polyglossia "brazilian" :lang-name "Portuges")
-    ("rm"  :babel-ini-only "romansh" :polyglossia "romansh" :lang-name "Romansh")
-    ("ro"  :babel "romanian" :polyglossia "romanian" :lang-name "Romanian")
-    ("ru"  :babel "russian" :polyglossia "russian" :lang-name "Russian")
-    ("sa"  :babel-ini-only "sanskrit" :polyglossia "sanskrit" :lang-name "Sanskrit")
-    ("sk"  :babel "slovak" :polyglossia "slovak" :lang-name "Slovak")
-    ("sl"  :babel "slovene" :polyglossia "slovene" :lang-name "Slovene")
-    ("sq"  :babel "albanian" :polyglossia "albanian" :lang-name "Albanian")
-    ("sr"  :babel "serbian" :polyglossia "serbian" :lang-name "Serbian")
-    ("sv"  :babel "swedish" :polyglossia "swedish" :lang-name "Swedish")
-    ("syr"  :babel-ini-only "syriac" :polyglossia "syriac" :lang-name "Syriac")
-    ("ta"  :babel-ini-only "tamil" :polyglossia "tamil" :lang-name "Tamil")
-    ("te"  :babel-ini-only "telugu" :polyglossia "telugu" :lang-name "Telugu")
-    ("th"  :babel "thai" :polyglossia "thai" :lang-name "Thai")
-    ("tk"  :babel "turkmen" :polyglossia "turkmen" :lang-name "Turkmen")
-    ("tr"  :babel "turkish" :polyglossia "turkish" :lang-name "Turkish")
-    ("uk"  :babel "ukrainian" :polyglossia "ukrainian" :lang-name "Ukrainian")
-    ("ur"  :babel-ini-only "urdu" :polyglossia "urdu" :lang-name "Urdu")
-    ("vi"  :babel "vietnamese" :polyglossia "vietnamese" :lang-name "Vietnamese"))
+  '(("af" :babel "afrikaans" :polyglossia "afrikaans" :lang-name "Afrikaans" :script "latin" :script-tag "latn")
+    ("am" :babel-ini-only "amharic" :polyglossia "amharic" :lang-name "Amharic" :script "ethiopic" :script-tag "ethi")
+    ("ar" :babel-ini-only "arabic" :polyglossia "arabic" :lang-name "Arabic" :script "arabic" :script-tag "arab")
+    ("ast" :babel-ini-only "asturian" :polyglossia "asturian" :lang-name "Asturian" :script "latin" :script-tag "latn")
+    ("bg"  :babel "bulgarian" :polyglossia "bulgarian" :lang-name "Bulgarian" :script "cyrillic" :script-tag "cyrl")
+    ("bn"  :babel-ini-only "bengali" :polyglossia "bengali" :lang-name "Bengali" :script "bengali" :script-tag: "beng")
+    ("bo"  :babel-ini-only "tibetan" :polyglossia "tibetan" :lang-name "Tibetan" :script "tibetan" :script-tag "tib")
+    ("br"  :babel "breton" :polyglossia "breton" :lang-name "Breton" :script "latin" :script-tag "latn")
+    ("ca"  :babel "catalan" :polyglossia "catalan" :lang-name "Catalan" :script "latin" :script-tag "latn")
+    ("cop"  :babel-ini-only "coptic" :polyglossia "coptic" :lang-name "Coptic" :script "coptic" :script-tag "copt")
+    ("cs"  :babel "czech" :polyglossia "czech" :lang-name "Czech" :script "latin" :script-tag "latn")
+    ("cy"  :babel "welsh" :polyglossia "welsh" :lang-name "Welsh" :script "latin" :script-tag "latn")
+    ("da"  :babel "danish" :polyglossia "danish" :lang-name "Danish" :script "latin" :script-tag "latn")
+    (("de" "de-de")  :babel "ngerman" :babel-ini-alt "german" :polyglossia "german" :polyglossia-variant "german" :lang-name "German" :script "latin" :script-tag "latn")
+    ("de-at"  :babel "naustrian" :babel-ini-alt "german-austria" :polyglossia "german" :polyglossia-variant "austrian" :lang-name "German" :script "latin" :script-tag "latn")
+    ("dsb"  :babel "lowersorbian" :babel-ini-alt "lsorbian" :polyglossia "sorbian" :polyglossia-variant "lower" :lang-name "Lower Sorbian" :script "latin" :script-tag "latn")
+    ("dv" :polyglossia "divehi" :lang-name "Dhivehi" :script "latin" :script-tag "latn")
+    ("el"  :babel "greek" :polyglossia "greek" :lang-name "Greek" :script "greek" :script-tag "grek")
+    ("el-polyton"  :babel "polutonikogreek" :babel-ini-alt "polytonicgreek" :polyglossia "greek" :polyglossia-variant "polytonic" :lang-name "Polytonic Greek" :script "greek" :script-tag "grek")
+    ("grc"  :babel "greek.ancient" :babel-ini-alt "ancientgreek" :polyglossia "greek" :polyglossia-variant "ancient" :lang-name "Ancient Greek" :script "greek" :script-tag "grek")
+    ("en"  :babel "english" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English" :script "latin" :script-tag "latn")
+    ("en-au"  :babel "australian" :polyglossia "english" :polyglossia-variant "australian" :lang-name "English" :script "latin" :script-tag "latn")
+    ("en-ca"  :babel "canadian" :polyglossia "english" :polyglossia-variant "canadian" :lang-name "English" :script "latin" :script-tag "latn")
+    ("en-gb"  :babel "british" :polyglossia "english" :polyglossia-variant "uk" :lang-name "English" :script "latin" :script-tag "latn")
+    ("en-nz"  :babel "newzealand" :polyglossia "english" :polyglossia-variant "newzealand" :lang-name "English" :script "latin" :script-tag "latn")
+    ("en-us"  :babel "american" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English" :script "latin" :script-tag "latn")
+    ("eo"  :babel "esperanto" :polyglossia "esperanto" :lang-name "Esperanto" :script "latin" :script-tag "latn")
+    ("es"  :babel "spanish" :polyglossia "spanish" :lang-name "Spanish" :script "latin" :script-tag "latn")
+    ("es-mx"  :babel "spanishmx" :polyglossia "spanish" :polyglossia-variant "mexican" :lang-name "Spanish" :script "latin" :script-tag "latn")
+    ("et"  :babel "estonian" :polyglossia "estonian" :lang-name "Estonian" :script "latin" :script-tag "latn")
+    ("eu"  :babel "basque" :polyglossia "basque" :lang-name "Basque" :script "latin" :script-tag "latn")
+    ("fa"  :babel "persian" :polyglossia "persian" :lang-name "Persian" :script "arabic" :script-tag "arab")
+    ("fi"  :babel "finnish" :polyglossia "finnish" :lang-name "Finnish" :script "latin" :script-tag "latn")
+    ("fr"  :babel "french" :polyglossia "french" :lang-name "French" :script "latin" :script-tag "latn")
+    ("fr-ca"  :babel "canadien" :babel-ini-alt "canadian" :polyglossia "french" :polyglossia-variant "canadian" :lang-name "French" :script "latin" :script-tag "latn")
+    ("fur"  :babel "friulian" :polyglossia "friulian" :lang-name "Friulian" :script "latin" :script-tag "latn")
+    ("ga"  :babel "irish" :polyglossia "gaelic" :polyglossia-variant "irish" :lang-name "Irish Gaelic" :script "latin" :script-tag "latn")
+    ("gd"  :babel "scottish" :polyglossia "gaelic" :polyglossia-variant "scottish" :lang-name "Scottish Gaelic" :script "latin" :script-tag "latn")
+    ("gl"  :babel "galician" :polyglossia "galician" :lang-name "Galician" :script "latin" :script-tag "latn")
+    ("he"  :babel "hebrew" :polyglossia "hebrew" :lang-name "Hebrew" :script "hebrew" :script-tag "hebr")
+    ("hi"  :babel "hindi" :polyglossia "hindi" :lang-name "Hindi" :script "devanagari" :script-tag "deva")
+    ("hr"  :babel "croatian" :polyglossia "croatian" :lang-name "Croatian" :script "latin" :script-tag "latn")
+    ("hsb"  :babel "uppersorbian" :polyglossia "sorbian" :polyglossia-variant "upper" :lang-name "Upper Sorbian" :script "latin" :script-tag "latn")
+    ("hu"  :babel "magyar" :polyglossia "magyar" :lang-name "Magyar" :script "latin" :script-tag "latn")
+    ("hy"  :babel-ini-only "armenian" :polyglossia "armenian" :lang-name "Armenian" :script "armenian" :script-tag "armn")
+    ("ia"  :babel "interlingua" :polyglossia "interlingua" :lang-name "Interlingua" :script "latin" :script-tag "latn")
+    ("id"  :babel "indonesian" :polyglossia "malay" :polyglossia-variant "indonesian" :lang-name "Indonesian" :script "latin" :script-tag "latn")
+    ("is"  :babel "icelandic" :polyglossia "icelandic" :lang-name "Icelandic" :script "latin" :script-tag "latn")
+    ("it"  :babel "italian" :polyglossia "italian" :lang-name "Italian" :script "latin" :script-tag "latn")
+    ("kn"  :babel-ini-only "kannada" :polyglossia "kannada" :lang-name "Kannada" :script "kannada" :script-tag "knda")
+    ("la"  :babel "latin" :polyglossia "latin" :lang-name "Latin" :script "latin" :script-tag "latn")
+    ("la-classic"  :babel "classiclatin" :polyglossia "latin" :polyglossia-variant "classic" :lang-name "Classic Latin" :script "latin" :script-tag "latn")
+    ("la-medieval"  :babel "medievallatin" :polyglossia "latin" :polyglossia-variant "medieval" :lang-name "Medieval Latin" :script "latin" :script-tag "latn")
+    ("la-ecclesiastic"  :babel "ecclesiasticlatin" :polyglossia "latin" :polyglossia-variant "ecclesiastic" :lang-name "Ecclesiastic Latin" :script "latin" :script-tag "latn")
+    ("lo"  :babel-ini-only "lao" :polyglossia "lao" :lang-name "Lao" :script "lao" :script-tag "lao")
+    ("lt"  :babel "lithuanian" :polyglossia "lithuanian" :lang-name "Lithuanian" :script "latin" :script-tag "latn")
+    ("lv"  :babel "latvian" :polyglossia "latvian" :lang-name "Latvian" :script "latin" :script-tag "latn")
+    ("ml"  :babel-ini-only "malayalam" :polyglossia "malayalam" :lang-name "Malayalam" :script "malayalam" :script-tag "mlym")
+    ("mr"  :babel-ini-only "marathi" :polyglossia "marathi" :lang-name "Marathi" :script "devanagari" :script-tag "deva")
+    ("ms"  :babel "malay" :polyglossia "malay" :polyglossia-variant "malaysian" :lang-name "Malay" :script "latin" :script-tag "latn")
+    ("nb"  :babel "norsk" :polyglossia "norwegian" :polyglossia-variant "bokmal" :lang-name "Norwegian Bokmål" :script "latin" :script-tag "latn")
+    ("nl"  :babel "dutch" :polyglossia "dutch" :lang-name "Dutch" :script "latin" :script-tag "latn")
+    ("nn"  :babel "nynorsk" :polyglossia "norwegian" :polyglossia-variant "nynorsk" :lang-name "Norwegian Nynorsk" :script "latin" :script-tag "latn")
+    ("no"  :babel "norsk" :polyglossia "norsk" :lang-name "Norwegian" :script "latin" :script-tag "latn")
+    ("oc"  :babel "occitan" :polyglossia "occitan" :lang-name "Occitan" :script "latin" :script-tag "latn")
+    ("pl"  :babel "polish" :polyglossia "polish" :lang-name "Polish" :script "latin" :script-tag "latn")
+    ("pms" :babel "piedmontese" :polyglossia "piedmontese" :lang-name "Piedmontese" :script "latin" :script-tag "latn")
+    ("pt"  :babel "portuges" :polyglossia "portuges" :lang-name "Portuges" :script "latin" :script-tag "latn")
+    ("pt-br" :babel "brazilian" :polyglossia "brazilian" :lang-name "Portuges" :script "latin" :script-tag "latn")
+    ("rm"  :babel-ini-only "romansh" :polyglossia "romansh" :lang-name "Romansh" :script "latin" :script-tag "latn")
+    ("ro"  :babel "romanian" :polyglossia "romanian" :lang-name "Romanian" :script "latin" :script-tag "latn")
+    ("ru"  :babel "russian" :polyglossia "russian" :lang-name "Russian" :script "cyrillic" :script-tag "cyrl")
+    ("sa"  :babel-ini-only "sanskrit" :polyglossia "sanskrit" :lang-name "Sanskrit" :script "devanagari" :script-tag "deva")
+    ("sk"  :babel "slovak" :polyglossia "slovak" :lang-name "Slovak" :script "latin" :script-tag "latn")
+    ("sl"  :babel "slovene" :polyglossia "slovene" :lang-name "Slovene" :script "latin" :script-tag "latn")
+    ("sq"  :babel "albanian" :polyglossia "albanian" :lang-name "Albanian" :script "latin" :script-tag "latn")
+    ("sr"  :babel "serbian" :polyglossia "serbian" :lang-name "Serbian" :script "latin" :script-tag "latn")
+    ("sr-cyrl" :babel-ini-only "serbian-cyrl" :polyglossia "serbian" :lang-name "Serbian" :script "cyrillic" :script-tag "cyrl")
+    ("sr-latn" :babel-ini-only "serbian-latin" :polyglossia "serbian" :lang-name "Serbian" :script "latin" :script-tag "latn")
+    ("sv"  :babel "swedish" :polyglossia "swedish" :lang-name "Swedish" :script "latin" :script-tag "latn")
+    ("syr" :babel-ini-only "syriac" :polyglossia "syriac" :lang-name "Syriac" :script "syriac" :script-tag "syrc")
+    ("ta"  :babel-ini-only "tamil" :polyglossia "tamil" :lang-name "Tamil" :script "tamil" :script-tag "taml")
+    ("te"  :babel-ini-only "telugu" :polyglossia "telugu" :lang-name "Telugu" :script "telugu" :script-tag "telu")
+    ("th"  :babel "thai" :polyglossia "thai" :lang-name "Thai" :script "thai" :script-tag "thai")
+    ("tk"  :babel "turkmen" :polyglossia "turkmen" :lang-name "Turkmen" :script "latin" :script-tag "latn")
+    ("tr"  :babel "turkish" :polyglossia "turkish" :lang-name "Turkish" :script "latin" :script-tag "latn")
+    ("uk"  :babel "ukrainian" :polyglossia "ukrainian" :lang-name "Ukrainian" :script "cyrillic" :script-tag "cyrl")
+    ("ur"  :babel-ini-only "urdu" :polyglossia "urdu" :lang-name "Urdu" :script "arabic" :script-tag "arab")
+    ("vi"  :babel "vietnamese" :polyglossia "vietnamese" :lang-name "Vietnamese" :script "latin" :script-tag "latn")
+    (("zh" "zh-cn")  :babel-ini-only "chinese" :polyglossia "chinese" :lang-name "Chinese Simplified" :script "hans" :script-tag "hans")
+    ("zh-tw"  :babel-ini-only "chinese-traditional" :polyglossia "chinese" :polyglossia-variant "traditional" :lang-name "Chinese Traditional" :script "hant" :script-tag "hant"))
   "Alist between language code and its properties for LaTeX export.
 
-In each element of the list car is always the code of the
-language and cdr is a property list.  Valid keywords for this
-list can be:
+In each element of the list car is always the language code or a
+list of languages codes and cdr is a property list.  Valid
+keywords for this list can be:
 
 - `:babel' the name of the language loaded by the Babel LaTeX package
 
@@ -275,9 +283,17 @@ list can be:
  exclusively through the new ini files method.  See
  `http://mirrors.ctan.org/macros/latex/required/babel/base/babel.pdf'
 
+- `:babel-ini-alt' an alternative language name when it is loaded
+  using ini files
+
 - `:polyglossia-variant' the language variant loaded by Polyglossia
 
-- `:lang-name' the actual name of the language.")
+- `:lang-name' the actual name of the language
+
+- `:script' the script name
+
+- `:script-tag' the script otf tag.")
+
 
 (defconst org-latex-line-break-safe "\\\\[0pt]"
   "Linebreak protecting the following [...].
@@ -1657,9 +1673,15 @@ already loaded.
 Return the new header."
   (let* ((language-code (plist-get info :language))
 	 (plist (cdr
-		 (assoc language-code org-latex-language-alist)))
+		 (cl-assoc-if (lambda (x)
+                                (or (and (stringp x)
+                                         (string= language-code x))
+                                    (and (listp x)
+                                         (member language-code x))))
+                              org-latex-language-alist)))
 	 (language (plist-get plist :babel))
 	 (language-ini-only (plist-get plist :babel-ini-only))
+         (language-ini-alt (plist-get plist :babel-ini-alt))
 	 ;; If no language is set, or Babel package is not loaded, or
 	 ;; LANGUAGE keyword value is a language served by Babel
 	 ;; exclusively through ini files, return HEADER as-is.
@@ -1691,7 +1713,8 @@ Return the new header."
 	    (replace-regexp-in-string (format
 				       "\\(\\\\babelprovide\\[.*\\]\\)\\({\\)%s}" prov)
 				      (format "\\1\\2%s}"
-					      (or language language-ini-only))
+					      (if language-ini-alt language-ini-alt
+                                                (or language language-ini-only)))
 				      header t)
 	  header)))))
 
@@ -1736,7 +1759,12 @@ Return the new header."
 		 (mapconcat
 		  (lambda (l)
 		    (let* ((plist (cdr
-				   (assoc language org-latex-language-alist)))
+				   (cl-assoc-if (lambda (x)
+                                                  (or (and (stringp x)
+                                                           (string= language x))
+                                                      (and (listp x)
+                                                           (member language x))))
+                                                org-latex-language-alist)))
 			   (polyglossia-variant (plist-get plist :polyglossia-variant))
 			   (polyglossia-lang (plist-get plist :polyglossia))
 			   (l (if (equal l language)
-- 
2.42.0


^ permalink raw reply related	[relevance 2%]

* [BUG] emergency exit [9.6.6 (release_9.6.6 @ /opt/homebrew/Cellar/emacs-mac/emacs-29.1-mac-10.0/share/emacs/29.1/lisp/org/)]
@ 2023-08-23  5:34  8% Jay Dixit
  0 siblings, 0 replies; 200+ results
From: Jay Dixit @ 2023-08-23  5:34 UTC (permalink / raw)
  To: org-mode org

[-- Attachment #1: Type: text/plain, Size: 81150 bytes --]

Remember to cover the basics, that is, what you expected to happen and
what in fact did happen.  You don't know how to make a good report?  See

     https://orgmode.org/manual/Feedback.html#Feedback

Your bug report will be posted to the Org mailing list.
------------------------------------------------------------------------

⛔ Warning (org-element-cache): org-element--cache: Got empty parent while
parsing. Please report it to Org mode mailing list (M-x
org-submit-bug-report).
 Backtrace:
nil
⛔ Warning (org-element-cache): org-element--cache: Got element without
parent. Please report it to Org mode mailing list (M-x
org-submit-bug-report).
(paragraph (:begin 220 :end 220 :contents-begin 220 :contents-end 221
:post-blank 0 :post-affiliated 220 :mode nil :granularity element :cached t
:parent nil))



Emacs  : GNU Emacs 29.1 (build 1, aarch64-apple-darwin22.5.0, Carbon
Version 169 AppKit 2299.6)
 of 2023-08-13
Package: Org mode version 9.6.6 (release_9.6.6 @
/opt/homebrew/Cellar/emacs-mac/emacs-29.1-mac-10.0/share/emacs/29.1/lisp/org/)

current state:
==============
(setq
 org-agenda-prefix-format '((agenda . " %?-12t% s") (timeline . "  % s")
(todo . " %i %-12:c") (tags . " %i %-12:c") (search . " %i %-12:c"))
 org-archive-location "archive/%s_archive::"
 org-link-elisp-confirm-function 'yes-or-no-p
 org-hierarchical-todo-statistics nil
 org-directory "~/Dropbox/writing/notationaldata/"
 org-roam-db-gc-threshold 20000000
 org-hide-emphasis-markers t
 org-yank-adjusted-subtrees t
 org-twbs-htmlize-output-type 'css
 org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
org-attach-id-uuid-folder-format)
 org-roam-dailies-capture-templates '(("j" "default" entry "* %?" :target
                                       (file+head "%<%Y-%m-%d>.org"
                                        "#+TITLE: %<%Y-%m-%d>\n#+FILETAGS:
:journal:\n- Links :: \n\n* %<%A, %B %d, %Y>\n- \n\n\n")
                                       )
                                      )
 org-agenda-custom-commands '(("r" "Review items" agenda ""
                               ((org-agenda-skip-function
'(org-agenda-skip-entry-if 'notregexp "::review::"))
                                (org-agenda-prefix-format " %i
%-12:c%?-12t% s") (org-agenda-overriding-header "Items to review"))
                               )
                              ("n" "Agenda and all TODOs" ((agenda "")
(alltodo ""))))
 org-twbs-format-drawer-function '(lambda (name contents) contents)
 org-timeblock-sort-function 'org-timeblock-order<
 org-startup-folded nil
 org-babel-after-execute-hook '(spacemacs/ob-fix-inline-images)
 org-startup-align-all-tables t
 org-capture-templates '(("L" "Later" checkitem (file+headline "fearless.org"
"Later") "\n\n [ ] %?\n\n" :prepend t :kill-buffer t)
                         ("n" "note" entry (file org-default-notes-file) "*
%? :NOTE:\n%U\n%a\n  %i" :prepend t :kill-buffer t :clock-in t
:clock-resume t)
                         ("b" "book" entry (file
"~/Dropbox/writing/book/book-capture.txt") "\n\n\n\n* %U\n\n%?\n\n\n"
:prepend t :kill-buffer t)
                         ("v" "visualness and visual actions" entry (file
"visual-actions.txt") "\n\n\n\n*  %? %i\n \n" :prepend t :kill-buffer t)
                         ("i" "article ideas" entry (file
"article-ideas.txt") "\n\n\n\n* %? %i\n \n" :prepend t :kill-buffer t)
                         ("e" "expression" entry (file "expression.txt")
"\n\n* %U\n  %i\n %?\n" :prepend t :kill-buffer t)
                         ("W" "Wise Mind" entry (file "wisemind.txt")
"\n\n* wm%?\n" :prepend t :kill-buffer t)
                         ("h" "historical interest" entry (file
"historical-lifestream.txt") "\n\n* %U\n  %i\n %?\n" :prepend t
:kill-buffer t)
                         ("P" "pages" entry (file
"~/Dropbox/writing/notationaldata/pages.txt") "\n\n\n\n* %U\n\n%?\n\n\n"
:prepend t :kill-buffer t)
                         ("s" "storytelling and writing" entry
                          (file
"/Users/jay/Dropbox/writing/writing-teacher/writing-teacher-stuff/teaching-writing-and-storytelling.txt")
                          "\n\n\n\n* %U\n\n%?" :prepend t :kill-buffer t)
                         ("F" "Funny" entry (file
"~/Dropbox/writing/notationaldata/funny.txt") "\n\n\n\n* %U\n\n%?\n"
:prepend t :kill-buffer t)
                         ("M" "Memorize" entry (file+headline (concat
org-directory "org-drill-jays-decks.org") "Vocabulary")
                          "* Word :drill:\n%^ \n** Answer \n%^")
                         ("f" "Fitness")
                         ("fw" "Weight" table-line (id
"7c721aac-eafa-4a42-9354-fbc151402510") "| | %U | %^{Weight} | %^{Comment}"
:immediate-finish t))
 org-roam-node-display-template #("${title:*} ${tags:15}" 11 21 (face
org-tag))
 org-indent-mode-turns-on-hiding-stars nil
 org-persist-after-read-hook '(org-element--cache-persist-after-read)
 org-latex-toc-command "\\tableofcontents\n\\newpage\n"
 org-time-stamp-custom-formats '("<%a %m/%e/%Y>" . "<%a %B %e %l:%M %p>")
 org-ai-default-chat-system-prompt "I'm Jay Dixit, a science writer,
adjunct professor of creative writing and storytelling, consultant, and
corporate trainer. I'm an expert on writing about psychology, and I used to
be an editor at Psychology Today Magazine. I've also written for The New
York Times. I offer professional workshops and training workshops in
business writing and storytelling. I would like to start offering corporate
training for companies on how to use ChatGPT, and I'm looking for clients.
I work on Mac OS, and I use Emacs org-mode and Bash scripts. You are a
helpful assistant inside Emacs."
 org-refile-targets '((my-org-files-list :maxlevel . 4))
 org-roam-file-exclude-regexp '("data/")
 org-export-before-parsing-hook '(org-export-id-link-removal
org-attach-expand-links
                                  (lambda (backend) (replace-regexp
"^\\([A-Za-z]+:\\)\\([^/]\\|/[^/]\\|$\\)" "*\\1*\\2")))
 org-clone-delete-id t
 org-cycle-tab-first-hook '(yas-org-very-safe-expand
org-babel-hide-result-toggle-maybe org-babel-header-arg-expand)
 org-tag-alist '(("important" . 105) ("urgent" . 117))
 org-html-doctype "html5"
 org-default-notes-file "~/Dropbox/writing/notationaldata/notes.txt"
 org-export-async-init-file
"/Users/jay/.emacs.d/layers/+emacs/org/local/org-async-init.el"
 org-roam-find-file-hook '(org-roam-buffer--setup-redisplay-h
org-roam--register-completion-functions-h
org-roam--replace-roam-links-on-save-h
                           org-roam-db-autosync--setup-update-on-save-h)
 org-refile-use-outline-path t
 org-publish-timestamp-directory "~/.emacs.d/.cache/.org-timestamps/"
 org-finalize-agenda-hook '((lambda nil (remove-text-properties (point-min)
(point-max) '(mouse-face t))))
 org-archive-hook '(my/org-archive-file org-attach-archive-delete-maybe)
 org-html-postamble nil
 org-odt-format-inlinetask-function
'org-odt-format-inlinetask-default-function
 org-edit-src-content-indentation 4
 org-ascii-format-drawer-function #[771 "%1\207" [] 4 "\n\n(fn NAME
CONTENTS WIDTH)"]
 org-cycle-hook '(org-cycle-hide-archived-subtrees
org-cycle-show-empty-lines org-cycle-optimize-window-after-visibility-change
                  org-cycle-display-inline-images)
 org-clocktable-defaults '(:maxlevel 3 :lang "en" :scope file :block nil
:wstart 1 :mstart 1 :tstart nil :tend nil :step nil :stepskip0 nil
:fileskip0 nil
                           :tags nil :emphasize nil :link nil :narrow 40!
:indent t :formula nil :timestamp nil :level nil :tcolumns nil :formatter
nil)
 org-enforce-todo-checkbox-dependencies t
 org-export-with-clocks t
 org-persist-before-read-hook '(org-element--cache-persist-before-read)
 org-twbs-head "<link href=\"
https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css\"
rel=\"stylesheet\"
integrity=\"sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9\"
crossorigin=\"anonymous\">\n<script src=\"
https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js\"
integrity=\"sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm\"
crossorigin=\"anonymous\"></script> "
 org-cycle-emulate-tab nil
 org-twbs-preamble nil
 org-modules '(org-mime)
 org-link-from-user-regexp "\\<jay@Rainlight\\.local\\>\\|\\<Sunjay E\\.
Dixit\\>"
 org-image-actual-width nil
 org-mode-hook '((lambda nil (redbold)) (lambda nil (add-hook
'window-configuration-change-hook 'activate-olivetti-in-split nil t))
                 (lambda nil (org-superstar-mode 1)) org-ai-mode #[0
"\301\211%10\207" [imenu-create-index-function org-imenu-get-tree] 2]
                 (lambda nil (define-key org-mode-map (kbd "DEL")
'new-org-delete-backward-char)) wrap-region-mode
turn-on-auto-capitalize-mode
                 (lambda nil (auto-fill-mode -1)) turn-on-visual-line-mode
flycheck-mode (lambda nil (flyspell-lazy-mode 1)) turn-on-flyspell
dubcaps-mode
                 org-clock-load org-tempo-setup
                 (lambda nil (make-variable-buffer-local 'yas--trigger-key)
(setq yas-trigger-key [tab])
                  (add-to-list 'org-tab-first-hook
'yas-org-very-safe-expand) (define-key yas-keymap [tab] 'yas-next-field))
                 wc-mode hl-todo-mode setup-org-mode-keys
                 #[0 "\300\301\302\303\304$\207" [add-hook
change-major-mode-hook org-fold-show-all append local] 5]
                 #[0 "\300\301\302\303\304$\207" [add-hook
change-major-mode-hook org-babel-show-result-all append local] 5]
org-babel-result-hide-spec
                 org-babel-hide-all-hashes flyspell-mode
spacemacs/load-yasnippet toc-org-enable org-superstar-mode
dotspacemacs//prettify-spacemacs-docs
                 org-eldoc-load)
 org-src-window-setup 'current-window
 org-ctrl-k-protect-subtree t
 org-id-locations-file "~/.emacs.d/.cache/.org-id-locations"
 org-highlight-links '(bracket plain radio tag date footnote)
 org-mime-html-hook '((lambda nil
                       (org-mime-change-element-style "blockquote"
                        "\n background:rgba(255,0,0,0.05);\n border:1px
solid rgba(255,0,0,0.2);\n border-radius:8px;\n color:#3f3f3f;\n
 font-family:monospace;\n line-height:1.2;\n  padding: 1em 1em 1em
1em;\nmargin-bottom: 1em;\n text-align:left;\n text-shadow:rgba(0,0,0,0.2)
0 2px 5px;\n white-space:0;\n  width:60%;\n  word-wrap:normal!important;")
                       )
                      (lambda nil
                       (org-mime-change-element-style "pre"
                        "color: #777;\n    quotes: none;\n
 border-radius: 15px;\n    font-weight: 400;\n    color: #87ceeb;\n
 line-height: 1.3em;\nwidth:80%;\n    background: none repeat scroll 0% 0%
rgb(61, 61, 61);\n    padding: 20px;\nquotes: '«' '»';\nfont-family:
Courier, 'Courier New', monospace;\n    font-weight: 400 !important;
font-size:small;")
                       )
                      (lambda nil
                       (org-mime-change-element-style "h2"
"color:#55C1E7;\n    font-family:Sans-Serif;\ntext-transform:capitalize;
font-weight:bold;"))
                      (lambda nil (org-mime-change-element-style "strong"
"font-family:sans-serif;color:#00ADEF;"))
                      (lambda nil (org-mime-change-element-style "li"
"font-family:sans-serif"))
                      (lambda nil
                       (org-mime-change-class-style "example"
                        "\n background:rgba(255,0,0,0.05);\n border:1px
solid rgba(255,0,0,0.2);\n border-radius:8px;\n color:#3f3f3f;\n
 font-family:monospace;\n line-height:1.2;\n  padding: 1em 1em 1em
1em;\nmargin-bottom: 1em;\nmargin-left:2em;\n text-align:left;\n
text-shadow:rgba(0,0,0,0.2) 0 2px 5px;\n white-space:0;\n  width:60%;\n
 word-wrap:normal!important;")
                       )
                      (lambda nil (org-mime-change-element-style "ul.org-ul
li a" "line-height: 1.5;"))
                      (lambda nil (org-mime-change-element-style "a"
"font-family:Helvetica,sans-serif; margin-bottom: 1em;"))
                      (lambda nil (org-mime-change-element-style "p"
"font-family:Helvetica,sans-serif; margin-bottom: 1em;"))
                      (lambda nil (goto-char (point-max))
                       (insert
                        "<br>\n<br>\n--<br>\n<strong><a href='
http://jaydixit.com/' style='text-decoration:none; color:#000;'
target='_blank'>Jay Dixit</a></strong><br>\nFounder, <a href='
http://storytelling.nyc/' style='text-decoration:none; color:#000;'
target='_blank'> Storytelling.NYC</a><br>\n<a href='http://jaydixit.com/'
style='text-decoration:none;' target='_blank'>\n  jaydixit.com</a>\n<br>\n<span
style='text-decoration:none;'><a href='http://storytelling.nyc/'
style='text-decoration:none;'
target='_blank'>storytelling.nyc</a><br></span>\n<span
style='text-decoration:none;'><a href='http://jaydixit.com/'
style='text-decoration:none; color:#000;' target='_blank'>(646)
355-8001</a><br></span>\n<a href='http://storytelling.nyc/'
style='text-decoration:none;' target='_blank'>\n<img src='
http://incandescentman.github.io/assets/images/storytelling-nyc-logo-final.png'
alt='Storytelling NYC' height='55'>\n</a>\n<a href='
https://twitter.com/jaydixit' style='text-decoration:none;'
target='_blank'>\n<img src='
http://incandescentman.github.io/assets/images/twitter-512.png' height=16
width=16 alt='New York Writers on Twitter'>\n</a>\n<a href='
https://www.facebook.com/newyorkwriters/' style='text-decoration:none;'
target='_blank'>\n<img src='
http://incandescentman.github.io/assets/images/facebook-512.png' height=16
width=16 alt='New York Writers on Facebook'>\n</a>\n<a href='
https://instagram.com/jaydixit' style='text-decoration:none;'
target='_blank'>\n<img src='
http://incandescentman.github.io/assets/images/instagram-icon-128.png'
height=16 width=16 alt='Jay Dixit on Instagram'>\n</a>\n<br>\n<p
style='color:#FFF;' target='_blank'>Jay Dixit</p>")
                       )
                      )
 org-html-head "<style type=\"text/css\">\n<!--/*--><![CDATA[/*><!--*/\n/*
Global variables. */\n:root,\n::backdrop {\n  /* Set sans-serif & mono
fonts */\n  --sans-font: -apple-system, BlinkMacSystemFont, \"Avenir
Next\", Avenir,\n    \"Nimbus Sans L\", Roboto, \"Noto Sans\", \"Segoe
UI\", Arial, Helvetica,\n    \"Helvetica Neue\", sans-serif;\n
 --mono-font: Consolas, Menlo, Monaco, \"Andale Mono\", \"Ubuntu Mono\",
monospace;\n  --standard-border-radius: 5px;\n\n  /* Default (light) theme
*/\n  --bg: #fff;\n  --accent-bg: #f5f7ff;\n  --text: #212121;\n
 --text-light: #585858;\n  --border: #898EA4;\n  --accent: #0d47a1;\n
 --code: #d81b60;\n  --preformatted: #444;\n  --marked: #ffdd33;\n
 --disabled: #efefef;\n}\n\n/* Dark theme */\n@media (prefers-color-scheme:
dark) {\n  :root,\n  ::backdrop {\n    color-scheme: dark;\n    --bg:
#212121;\n    --accent-bg: #2b2b2b;\n    --text: #dcdcdc;\n
 --text-light: #ababab;\n    --accent: #ffb300;\n    --code: #f06292;\n
 --preformatted: #ccc;\n    --disabled: #111;\n  }\n  /* Add a bit of
transparency so light media isn't so glaring in dark mode */\n  img,\n
 video {\n    opacity: 0.8;\n  }\n}\n\n/* Reset box-sizing */\n*,
*::before, *::after {\n  box-sizing: border-box;\n}\n\n/* Reset default
appearance */\ntextarea,\nselect,\ninput,\nprogress {\n  appearance:
none;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n}\n\nhtml {\n
 /* Set the font globally */\n  font-family: var(--sans-font);\n
 scroll-behavior: smooth;\n}\n\n/* Make the body a nice central block
*/\nbody {\n  color: var(--text);\n  background-color: var(--bg);\n
 font-size: 1.15rem;\n  line-height: 1.5;\n  display: grid;\n
 grid-template-columns: 1fr min(45rem, 90%) 1fr;\n  margin: 0;\n}\nbody > *
{\n  grid-column: 2;\n}\n\n/* Make the header bg full width, but the
content inline with body */\nbody > header {\n  background-color:
var(--accent-bg);\n  border-bottom: 1px solid var(--border);\n  text-align:
center;\n  padding: 0 0.5rem 2rem 0.5rem;\n  grid-column: 1 /
-1;\n}\n\nbody > header h1 {\n  max-width: 1200px;\n  margin: 1rem
auto;\n}\n\nbody > header p {\n  max-width: 40rem;\n  margin: 1rem
auto;\n}\n\n/* Add a little padding to ensure spacing is correct between
content and header > nav */\nmain {\n  padding-top: 1.5rem;\n}\n\nbody >
footer {\n  margin-top: 4rem;\n  padding: 2rem 1rem 1.5rem 1rem;\n  color:
var(--text-light);\n  font-size: 0.9rem;\n  text-align: center;\n
 border-top: 1px solid var(--border);\n}\n\n/* Format headers */\nh1 {\n
 font-size: 3rem;\n}\n\nh2 {\n  font-size: 2.6rem;\n  margin-top:
3rem;\n}\n\nh3 {\n  font-size: 2rem;\n  margin-top: 3rem;\n}\n\nh4 {\n
 font-size: 1.44rem;\n}\n\nh5 {\n  font-size: 1.15rem;\n}\n\nh6 {\n
 font-size: 0.96rem;\n}\n\n/* Prevent long strings from overflowing
container */\np, h1, h2, h3, h4, h5, h6 {\n  overflow-wrap:
break-word;\n}\n\n/* Fix line height when title wraps */\nh1,\nh2,\nh3 {\n
 line-height: 1.1;\n}\n\n/* Reduce header size on mobile */\n@media only
screen and (max-width: 720px) {\n  h1 {\n    font-size: 2.5rem;\n  }\n\n
 h2 {\n    font-size: 2.1rem;\n  }\n\n  h3 {\n    font-size: 1.75rem;\n
 }\n\n  h4 {\n    font-size: 1.25rem;\n  }\n}\n\n/* Format links & buttons
*/\na,\na:visited {\n  color: var(--accent);\n}\n\na:hover {\n
 text-decoration:
none;\n}\n\nbutton,\n[role=\"button\"],\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"],\nlabel[type=\"button\"]
{\n  border: none;\n  border-radius: var(--standard-border-radius);\n
 background-color: var(--accent);\n  font-size: 1rem;\n  color:
var(--bg);\n  padding: 0.7rem 0.9rem;\n  margin: 0.5rem 0;\n\n  /* Ensure
buttons use correct font */\n  font-family:
inherit;\n}\n\nbutton[disabled],\n[role=\"button\"][aria-disabled=\"true\"],\ninput[type=\"submit\"][disabled],\ninput[type=\"reset\"][disabled],\ninput[type=\"button\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"][disabled],\nselect[disabled]
{\n  cursor:
not-allowed;\n}\n\ninput:disabled,\ntextarea:disabled,\nselect:disabled,\nbutton[disabled]
{\n  cursor: not-allowed;\n  background-color: var(--disabled);\n  color:
var(--text-light)\n}\n\ninput[type=\"range\"] {\n  padding: 0;\n}\n\n/* Set
the cursor to '?' on an abbreviation and style the abbreviation to show
that there is more information underneath */\nabbr[title] {\n  cursor:
help;\n  text-decoration-line: underline;\n  text-decoration-style:
dotted;\n}\n\nbutton:enabled:hover,\n[role=\"button\"]:not([aria-disabled=\"true\"]):hover,\ninput[type=\"submit\"]:enabled:hover,\ninput[type=\"reset\"]:enabled:hover,\ninput[type=\"button\"]:enabled:hover,\nlabel[type=\"button\"]:hover
{\n  filter: brightness(1.4);\n  cursor:
pointer;\n}\n\nbutton:focus-visible:where(:enabled,
[role=\"button\"]:not([aria-disabled=\"true\"])),\ninput:enabled:focus-visible:where(\n
 [type=\"submit\"],\n  [type=\"reset\"],\n  [type=\"button\"]\n) {\n
 outline: 2px solid var(--accent);\n  outline-offset: 1px;\n}\n\n/* Format
navigation */\nheader > nav {\n  font-size: 1rem;\n  line-height: 2;\n
 padding: 1rem 0 0 0;\n}\n\n/* Use flexbox to allow items to wrap, as
needed */\nheader > nav ul,\nheader > nav ol {\n  align-content:
space-around;\n  align-items: center;\n  display: flex;\n  flex-direction:
row;\n  flex-wrap: wrap;\n  justify-content: center;\n  list-style-type:
none;\n  margin: 0;\n  padding: 0;\n}\n\n/* List items are inline elements,
make them behave more like blocks */\nheader > nav ul li,\nheader > nav ol
li {\n  display: inline-block;\n}\n\nheader > nav a,\nheader > nav
a:visited {\n  margin: 0 0.5rem 1rem 0.5rem;\n  border: 1px solid
var(--border);\n  border-radius: var(--standard-border-radius);\n  color:
var(--text);\n  display: inline-block;\n  padding: 0.1rem 1rem;\n
 text-decoration: none;\n}\n\nheader > nav a:hover,\nheader > nav
a.current,\nheader > nav a[aria-current=\"page\"] {\n  border-color:
var(--accent);\n  color: var(--accent);\n  cursor: pointer;\n}\n\n/* Reduce
nav side on mobile */\n@media only screen and (max-width: 720px) {\n
 header > nav a {\n    border: none;\n    padding: 0;\n    text-decoration:
underline;\n    line-height: 1;\n  }\n}\n\n/* Consolidate box styling
*/\naside, details, pre, progress {\n  background-color:
var(--accent-bg);\n  border: 1px solid var(--border);\n  border-radius:
var(--standard-border-radius);\n  margin-bottom: 1rem;\n}\n\naside {\n
 font-size: 1rem;\n  width: 30%;\n  padding: 0 15px;\n
 margin-inline-start: 15px;\n  float: right;\n}\n*[dir=\"rtl\"] aside {\n
 float: left;\n}\n\n/* Make aside full-width on mobile */\n@media only
screen and (max-width: 720px) {\n  aside {\n    width: 100%;\n    float:
none;\n    margin-inline-start: 0;\n  }\n}\n\narticle, fieldset, dialog {\n
 border: 1px solid var(--border);\n  padding: 1rem;\n  border-radius:
var(--standard-border-radius);\n  margin-bottom: 1rem;\n}\n\narticle
h2:first-child,\nsection h2:first-child {\n  margin-top:
1rem;\n}\n\nsection {\n  border-top: 1px solid var(--border);\n
 border-bottom: 1px solid var(--border);\n  padding: 2rem 1rem;\n  margin:
3rem 0;\n}\n\n/* Don't double separators when chaining sections */\nsection
+ section,\nsection:first-child {\n  border-top: 0;\n  padding-top:
0;\n}\n\nsection:last-child {\n  border-bottom: 0;\n  padding-bottom:
0;\n}\n\ndetails {\n  padding: 0.7rem 1rem;\n}\n\nsummary {\n  cursor:
pointer;\n  font-weight: bold;\n  padding: 0.7rem 1rem;\n  margin: -0.7rem
-1rem;\n  word-break: break-all;\n}\n\ndetails[open] > summary + * {\n
 margin-top: 0;\n}\n\ndetails[open] > summary {\n  margin-bottom:
0.5rem;\n}\n\ndetails[open] > :last-child {\n  margin-bottom: 0;\n}\n\n/*
Format tables */\ntable {\n  border-collapse: collapse;\n  margin: 1.5rem
0;\n}\n\ntd,\nth {\n  border: 1px solid var(--border);\n  text-align:
start;\n  padding: 0.5rem;\n}\n\nth {\n  background-color:
var(--accent-bg);\n  font-weight: bold;\n}\n\ntr:nth-child(even) {\n  /*
Set every other cell slightly darker. Improves readability. */\n
 background-color: var(--accent-bg);\n}\n\ntable caption {\n  font-weight:
bold;\n  margin-bottom: 0.5rem;\n}\n\n/* Format forms
*/\ntextarea,\nselect,\ninput {\n  font-size: inherit;\n  font-family:
inherit;\n  padding: 0.5rem;\n  margin-bottom: 0.5rem;\n  color:
var(--text);\n  background-color: var(--bg);\n  border: 1px solid
var(--border);\n  border-radius: var(--standard-border-radius);\n
 box-shadow: none;\n  max-width: 100%;\n  display: inline-block;\n}\nlabel
{\n  display: block;\n}\ntextarea:not([cols]) {\n  width: 100%;\n}\n\n/*
Add arrow to drop-down */\nselect:not([multiple]) {\n  background-image:
linear-gradient(45deg, transparent 49%, var(--text) 51%),\n
 linear-gradient(135deg, var(--text) 51%, transparent 49%);\n
 background-position: calc(100% - 15px), calc(100% - 10px);\n
 background-size: 5px 5px, 5px 5px;\n  background-repeat: no-repeat;\n
 padding-inline-end: 25px;\n}\n*[dir=\"rtl\"] select:not([multiple]) {\n
 background-position: 10px, 15px;\n}\n\n/* checkbox and radio button style
*/\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  vertical-align:
middle;\n  position: relative;\n  width:
min-content;\n}\n\ninput[type=\"checkbox\"] + label,\ninput[type=\"radio\"]
+ label {\n  display: inline-block;\n}\n\ninput[type=\"radio\"] {\n
 border-radius:
100%;\n}\n\ninput[type=\"checkbox\"]:checked,\ninput[type=\"radio\"]:checked
{\n  background-color:
var(--accent);\n}\n\ninput[type=\"checkbox\"]:checked::after {\n  /*
Creates a rectangle with colored right and bottom borders which is rotated
to look like a check mark */\n  content: \" \";\n  width: 0.18em;\n
 height: 0.32em;\n  border-radius: 0;\n  position: absolute;\n  top:
0.05em;\n  left: 0.17em;\n  background-color: transparent;\n  border-right:
solid var(--bg) 0.08em;\n  border-bottom: solid var(--bg) 0.08em;\n
 font-size: 1.8em;\n  transform:
rotate(45deg);\n}\ninput[type=\"radio\"]:checked::after {\n  /* creates a
colored circle for the checked radio button  */\n  content: \" \";\n
 width: 0.25em;\n  height: 0.25em;\n  border-radius: 100%;\n  position:
absolute;\n  top: 0.125em;\n  background-color: var(--bg);\n  left:
0.125em;\n  font-size: 32px;\n}\n\n/* Makes input fields wider on smaller
screens */\n@media only screen and (max-width: 720px) {\n  textarea,\n
 select,\n  input {\n    width: 100%;\n  }\n}\n\n/* Set a height for color
input */\ninput[type=\"color\"] {\n  height: 2.5rem;\n  padding:
 0.2rem;\n}\n\n/* do not show border around file selector button
*/\ninput[type=\"file\"] {\n  border: 0;\n}\n\n/* Misc body elements */\nhr
{\n  border: none;\n  height: 1px;\n  background: var(--border);\n  margin:
1rem auto;\n}\n\nmark {\n  padding: 2px 5px;\n  border-radius:
var(--standard-border-radius);\n  background-color: var(--marked);\n
 color: black;\n}\n\nimg,\nvideo {\n  max-width: 100%;\n  height: auto;\n
 border-radius: var(--standard-border-radius);\n}\n\nfigure {\n  margin:
0;\n  display: block;\n  overflow-x: auto;\n}\n\nfigcaption {\n
 text-align: center;\n  font-size: 0.9rem;\n  color: var(--text-light);\n
 margin-bottom: 1rem;\n}\n\nblockquote {\n  margin-inline-start: 2rem;\n
 margin-inline-end: 0;\n  margin-block: 2rem;\n  padding: 0.4rem 0.8rem;\n
 border-inline-start: 0.35rem solid var(--accent);\n  color:
var(--text-light);\n  font-style: italic;\n}\n\ncite {\n  font-size:
0.9rem;\n  color: var(--text-light);\n  font-style: normal;\n}\n\ndt {\n
 color: var(--text-light);\n}\n\n/* Use mono font for code elements
*/\ncode,\npre,\npre span,\nkbd,\nsamp {\n  font-family:
var(--mono-font);\n  color: var(--code);\n}\n\nkbd {\n  color:
var(--preformatted);\n  border: 1px solid var(--preformatted);\n
 border-bottom: 3px solid var(--preformatted);\n  border-radius:
var(--standard-border-radius);\n  padding: 0.1rem 0.4rem;\n}\n\npre {\n
 padding: 1rem 1.4rem;\n  max-width: 100%;\n  overflow: auto;\n  color:
var(--preformatted);\n}\n\n/* Fix embedded code within pre */\npre code {\n
 color: var(--preformatted);\n  background: none;\n  margin: 0;\n  padding:
0;\n}\n\n/* Progress bars */\n/* Declarations are repeated because you
*/\n/* cannot combine vendor-specific selectors */\nprogress {\n  width:
100%;\n}\n\nprogress:indeterminate {\n  background-color:
var(--accent-bg);\n}\n\nprogress::-webkit-progress-bar {\n  border-radius:
var(--standard-border-radius);\n  background-color:
var(--accent-bg);\n}\n\nprogress::-webkit-progress-value {\n
 border-radius: var(--standard-border-radius);\n  background-color:
var(--accent);\n}\n\nprogress::-moz-progress-bar {\n  border-radius:
var(--standard-border-radius);\n  background-color: var(--accent);\n
 transition-property: width;\n  transition-duration:
0.3s;\n}\n\nprogress:indeterminate::-moz-progress-bar {\n
 background-color: var(--accent-bg);\n}\n\ndialog {\n  max-width: 40rem;\n
 margin: auto;\n}\n\ndialog::backdrop {\n  background-color: var(--bg);\n
 opacity: 0.8;\n}\n\n@media only screen and (max-width: 720px) {\n  dialog
{\n    max-width: 100%;\n    margin: auto 1em;\n  }\n}\n\n/* Classes for
buttons and notices */\n.button,\n.button:visited {\n  display:
inline-block;\n  text-decoration: none;\n  border: none;\n  border-radius:
5px;\n  background: var(--accent);\n  font-size: 1rem;\n  color:
var(--bg);\n  padding: 0.7rem 0.9rem;\n  margin: 0.5rem
0;\n}\n\n.button:hover,\n.button:focus {\n  filter: brightness(1.4);\n
 cursor: pointer;\n}\n\n.notice {\n  background: var(--accent-bg);\n
 border: 2px solid var(--border);\n  border-radius: 5px;\n  padding:
1.5rem;\n  margin: 2rem 0;\n}\n\n\n\n\n\n\n\n\n\n\n/* add the
hierarchy*/\ndiv.outline-text-3 {\n
 margin-left:1em;\n}\n\ndiv.outline-text-4{\n
 margin-left:0.2em\n\n}\n\ndiv.outline-text-5{\n
 margin-left:3em\n}\n\ndiv.outline-text-6 {\n
 margin-left:6em\n}\n\n\ndiv.outline-text-7 {\n
 margin-left:9em\n}\n\n\n\n\n\ndiv dl dt::after {\n content:
\":\";}\n\n\nh1 { color: #111; font-family: 'Helvetica Neue', sans-serif;
font-size: 4em; font-weight: bold; letter-spacing: -1px; line-height: 1;
text-align: center;   margin-bottom: 16px}\n\n\n\nh2\n{\n    font-family:
'Helvetica Neue', sans-serif;\n    font-weight: 100;\n    font-size:3em;\n
   line-height: 32px;\n    padding-bottom:0.2em;\n    margin-right:auto ;\n
   margin-top:1em;\n  margin-bottom: 0.5em;\n}\n\n\nh3 {\n  font-size:
1.3em;\n  margin-left:2em;\n}\n\nh4 {\n  font-size: 1.1em;\n
 margin-left: 0.2em;\n}\n\n\nh5\n{\nmargin-left:3em\n}\n\nh6\n{\n
 margin-left:6em ;\n      font-size: 1em;\n}\n\nh7\n{\n    margin-left:9em
;\n      font-size: 1em;\n      font-weight:bold;\n}\n\n\nli ul li {\n
 margin:0;\n}\n\n\n\nh1.title {\n
 text-align:left;\n}\n\n\ndiv.outline-text-3\n{margin-left:
2.6em;}\n\nh1:first-letter, h2:first-letter, h3:first-letter,
h4:first-letter, h5:first-letter\n{\ntext-transform:capitalize;\n}\n\ndiv
dl dt {\n  font-weight:700;\n}\n\n\npre, blockquote {\n    border-radius:
8px;\n    padding: 0 1em 1em;\n    text-align: left;\n    white-space:
pre-wrap;\n    word-wrap: break-word;\n}\n\n\ndiv.outline-text-3 {\n
 margin-left:5em;\n}\n\n\n\nli > p, li > ul, li > .inlinetask, li > dl {\n
   margin-left: 0px;\n}\n\ndd > p, dd > ul, dd > .inlinetask, dd > dl {\n
 margin-left: 0px;\n}\n\n\ndiv dl dt {\n  font-size:125%;\n\n}\n\ndiv dl
dt::first-letter\n{\n  text-transform: capitalize;\n}\n\n\ndiv blockquote p
{\n  font-size:200%;\n  margin:0;\n}\n\nh2 {\n  line-height:
1;\n}\n\n\nh1.title {\n  display:none;\n}\n\n\npre.example {\n
 padding-top:1em\n}\n/*]]>*/-->\n</style>\n"
 org-roam-ref-annotation-function 'org-roam-ref-read--annotation
 org-roam-directory "/Users/jay/Dropbox/roam"
 org-twbs-format-inlinetask-function 'ignore
 org-export-allow-bind-keywords t
 org-latex-format-drawer-function #[514 "\207" [] 3 "\n\n(fn _ CONTENTS)"]
 org-ellipsis " "
 org-ai-openai-api-token
"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"
 org-custom-properties '(">")
 org-roam-db-node-include-function #[0 "\300\207" [t] 1]
 org-export-exclude-tags '("noexport" "extra")
 org-latex-format-headline-function
'org-latex-format-headline-default-function
 org-confirm-shell-link-function 'yes-or-no-p
 org-ai-default-chat-model "gpt-4"
 org-present-mode-hook '(spacemacs//org-present-start)
 org-projectile-per-project-filepath "TODOs.org"
 org-export-with-section-numbers nil
 org-present-mode-quit-hook '(spacemacs//org-present-end)
 org-tempo-keywords-alist '(("l " . "src emacs-lisp ") ("H" . "html") ("A"
. "ascii") ("i" . "index"))
 org-html-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME CONTENTS)"]
 outline-isearch-open-invisible-function 'outline-isearch-open-invisible
 org-export-time-stamp-file nil
 org-roam-dailies-directory "journal/"
 org-startup-indented t
 org-export-before-processing-hook '(my-org-inline-css-hook
org-blackfriday--reset-org-blackfriday--code-block-num-backticks)
 org-ascii-headline-spacing '(1 . 1)
 org-latex-classes '(("blue-invoice"

"\n\n\\documentclass[12pt]{article}\n\\usepackage[includeheadfoot,margin=1.0in,hmargin=1.0in,vmargin=0.5in]{geometry}\n\\usepackage{float}\n\\usepackage{changepage}\n\n\\usepackage{algorithm}\n\\usepackage{amsmath}\n\\usepackage{ifxetex}\n\\ifxetex\n
 \\usepackage{fontspec,xltxtra,xunicode}\n
 \\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}\n\n\n% define
Helvetica Now font weights\n\\setmainfont{EBGaramond}[\n  Path =
/Users/jay/Library/Fonts/,\n        UprightFont = HelveticaNowText-Light,\n
       BoldFont = HelveticaNowDisplay-Bold,\n        ItalicFont =
HelveticaNowText-LightItalic,\n        BoldItalicFont =
HelveticaNowDisplay-BoldIta,\n  Extension =
.ttf\n\n\\setromanfont{HelveticaNowText-Light}\n\\setsansfont{HelveticaNowDisplay-Regular}\n\\newfontfamily{\\thindisplayfont}{HelveticaNowDisplay-Light}\n\\setmonofont{Myriad
Pro}\n\\else\n  \\usepackage[mathletters]{ucs}\n
 \\usepackage[utf8x]{inputenc}\n\\fi\n\\usepackage{url}\n\\usepackage{paralist}\n\\usepackage{graphicx}\n\\setkeys{Gin}{resolution=72}\n\\usepackage{tikz}\n\\usepackage{calc}\n\\usepackage{eso-pic}\n\\usepackage{etoolbox}\n\\usepackage{xcolor}\n\\PassOptionsToPackage{hyperref,x11names}{xcolor}\n\\definecolor{pinterestred}{HTML}{C92228}\n\\definecolor{ulyssesbutterflyblue}{HTML}{1464F4}\n\\definecolor{signalflare}{HTML}{FB782C}\n\\definecolor{niceorange}{HTML}{77CC6D}\n\\definecolor{ghostlygrey}{HTML}{000000}\n\\definecolor{firstcolor}{HTML}{00ADEF}\n\\definecolor{secondcolor}{HTML}{DD3E74}\n\\definecolor{periodblue}{HTML}{12239e}\n\\definecolor{denimblue}{HTML}{3A5F90}\n\\definecolor{electricblue}{HTML}{05ADF3}\n\\definecolor{resonateblue}{HTML}{005778}\n\\definecolor{resonateorange}{HTML}{da7635}\n\\definecolor{resonategrey}{HTML}{4d4d4c}\n\\definecolor{nliblue}{HTML}{2f9ed3}\n\\definecolor{elegantblue}{HTML}{1792d1}\n\\definecolor{ideablue}{HTML}{55C1E7}\n\n\n\\newtoks\\leftheader\n\\newtoks\\leftheaderurl\n\\newtoks\\coverimage\n\\newtoks\\rightheader\n\n\\raggedright\n\\hyphenpenalty=5000\n\\tolerance=1000\n\n\n\\renewcommand{\\contentsname}{Invoice}\n\n\n\n%This
macro is to make cleaner the specification of the titling
font\n\\newfontfamily\\mytitlefont[Color={highlighteryellow}]{Arial}\n\\newfontfamily\\myauthorfont[Color={highlighteryellow}]{Arial}\n\\newfontfamily\\mybluefont[Color=ideablue]{Arial}\n\n%Define
Bold
face\n\\DeclareTextFontCommand{\\textbf}{\\sffamily\\bfseries}\n\\DeclareTextFontCommand{\\textit}{\\itshape}\n\n\\usepackage{textcase}\n\n\\pagenumbering{arabic}\n\\makeatletter\n\n\n\\setcounter{secnumdepth}{0}\n\n\n\\usepackage[labelformat=empty]{caption}\n\n\\usepackage{fancyhdr}\n\\pagestyle{fancy}\n\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}\n\\lhead{\\href{\\the\\leftheaderurl}{\\the\\leftheader}}\n\\chead{}\n\\rhead{Invoice:
\\@title\\
 {\\nouppercase{\\the\\rightheader}}}\n\\lfoot{}\n\\cfoot{}\n\\rfoot{}\n\\usepackage{listings}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{12pt
plus 2pt minus 1pt} % space between paragraphs\n\n% spacing: how to read
{12pt plus 4pt minus 2pt}\n%           12pt is what we would like the
spacing to be\n%           plus 4pt means that TeX can stretch it by at
most 4pt\n%           minus 2pt means that TeX can shrink it by at most
2pt\n%       This is one example of the concept of, 'glue', in
TeX\n\n\\usepackage{fancyvrb}\n\\usepackage{enumerate}\n\\usepackage{ctable}\n\\setlength{\\paperwidth}{8.5in}\n\\setlength{\\paperheight}{11in}\n
 \\tolerance=1000\n\\usepackage{tocloft}\n\\renewcommand{\\cftsecleader}{\\cftdotfill{\\cftdotsep}}\n\\usepackage[normalem]{ulem}\n\n\n\\makeatletter\n\\newcommand{\\globalcolor}[1]{%\n
 \\color{#1}\\global\\let\\default@color\\current@color\n}\n\\makeatother\n\n\\newcommand{\\textsubscr}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}\n\n\\usepackage{enumitem}\n\n\\newlist{mylist}{enumerate}{10}\n\n\n%
control line spacing in bulleted list\n\\setlist{noitemsep, topsep=-8pt,
after=\\vspace{12pt}} % for no spacing between list items\n% see:
https://tex.stackexchange.com/questions/199118/modifying-whitespace-before-and-after-list-separately-using-enumitem-package\n%\\setlist{topsep=0pt}
% for a line between list items\n\n\n\\renewcommand{\\labelitemi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemviii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemix}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemx}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\n\\setlistdepth{10}\n\\setlist[itemize,1]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,2]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,3]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,4]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,5]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,6]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,7]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,8]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,9]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,10]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\renewlist{itemize}{itemize}{10}\n\n\n\n\n\n\\definecolor{azure}{HTML}{f2feff}\n\n\\usepackage{lipsum}\n\\usepackage{tikz}\n\\usetikzlibrary{backgrounds}\n\\makeatletter\n\n\\tikzset{%\n
 fancy quotes/.style={\n    text width=\\fq@width pt,\n    align=justify,\n
   inner sep=1em,\n    anchor=north west,\n    minimum width=\\linewidth,\n
 },\n  fancy quotes width/.initial={.8\\linewidth},\n  fancy quotes
marks/.style={\n    scale=8,\n    text=black,\n    inner sep=0pt,\n  },\n
 fancy quotes opening/.style={\n    fancy quotes marks,\n  },\n  fancy
quotes closing/.style={\n    fancy quotes marks,\n  },\n  fancy quotes
background/.style={\n    show background rectangle,\n    inner frame
xsep=0pt,\n    background rectangle/.style={\n      fill=azure,\n
 rounded corners,\n    },\n
 }\n}\n\n\\newenvironment{fancyquotes}[1][]{%\n\\noindent\n\\tikzpicture[fancy
quotes background]\n\\node[fancy quotes opening,anchor=north west] (fq@ul)
at (0,0) {``};\n\\tikz@scan@one@point\\pgfutil@firstofone(fq@ul.east
)\n\\pgfmathsetmacro{\\fq@width}{\\linewidth - 2*\\pgf@x}\n\\node[fancy
quotes,#1] (fq@txt) at (fq@ul.north west)
\\bgroup}\n{\\egroup;\n\\node[overlay,fancy quotes closing,anchor=east] at
(fq@txt.south east)
{''};\n\\endtikzpicture}\n\\makeatother\n\n%\\setlength{\\intextsep}{10pt
plus 1.0pt minus 2.0pt}\n\n\\newenvironment{indentedsection}\n
 {\\adjustwidth{2em}{0pt}}\n
 {\\endadjustwidth}\n\n\n\\usepackage{setspace}\n\\usepackage{lipsum}\n\\usepackage{etoolbox}\n\\AtBeginEnvironment{quote}{\\singlespace\\vspace{-\\topsep}\\small}\n\\AtEndEnvironment{quote}{\\vspace{-\\topsep}\\endsinglespace}\n\n\n\\usepackage[sc]{titlesec}\n\n\n\\newlength\\TitleOverhang\n\\setlength\\TitleOverhang{1.5cm}\n\n\\newcommand\\Overhang[1]{%\n
\\llap{\\makebox[\\TitleOverhang][l]{#1}}%\n}\n\n\n%
\\titlespacing{command}{left spacing}{before spacing}{after
spacing}[right]\n\\titlespacing*{\\section}{0pt}{16pt}{-6pt}\n\\titlespacing*{\\subsection}{0pt}{16pt}{-6pt}\n\\titlespacing*{\\subsubsection}{0pt}{6pt}{-6pt}\n\n\n\\titleformat*{\\section}{\\sffamily\\bfseries\\fontsize{30}{20}\\raggedright\\sffamily\\scshape\\color{ideablue}}\n\\titleformat*{\\subsection}{\\sffamily\\fontsize{18}{15}\\raggedright\\scshape\\color{ideablue}}\n\\titleformat*{\\subsubsection}{\\sffamily\\bfseries\\fontsize{14}{16}\\raggedright\\sffamily\\color{ideablue}}\n\\titleformat*{\\paragraph}{\\sffamily\\fontsize{13}{12}\\raggedright\\bfseries\\color{ideablue}}\n\\titleformat*{\\subparagraph}{\\sffamily\\fontsize{14}{14}\\raggedright\\bfseries\\ttfamily\\color{ideablue}}\n\n\n\\DeclareTextFontCommand{\\nonsection}{\\sffamily\\fontsize{19}{19}\\raggedright\\sffamily\\textlf\\color{ideablue}
}\n\n\\DeclareTextFontCommand{\\nonsubsection}{\\sffamily\\fontsize{18}{15}\\raggedright\\scshape\\color{ideablue}}\n\n\\DeclareTextFontCommand{\\nonsubsubsection}{\\sffamily\\itshape\\fontsize{14}{14}\\raggedright\\sffamily\\color{ideablue}
}\n\n\n\\usepackage[breaklinks=true,linktocpage,xetex]{hyperref}\n\\hypersetup{colorlinks,
citecolor=ideablue,filecolor=ideablue,linkcolor=ideablue,urlcolor=ideablue}\n\n\\renewcommand\\maketitle{}\n\n\n
     [NO-DEFAULT-PACKAGES]\n      [NO-PACKAGES]"
                      ("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" .
"\\subsubsection*{%s}")
                      ("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
                     ("beautiful-racket"

"\n\n\\documentclass[12pt]{article}\n\\usepackage[includeheadfoot,margin=1.5in,hmargin=1.5in,vmargin=0.5in]{geometry}
% for normal margins\n\n% Use the geometry package to customize the page
layout, margins, and other aspects of your document's
appearance\n\n\n\\usepackage{wrapfig}\n\n\n% To have more control over
figure placement in your document, use the float package and its [H] option
to place figures exactly where you want them in the
text:\n\\usepackage{float}\n\n\n% \\usepackage{glossaries}\n%
\\makeglossaries\n\n\\usepackage{todonotes}\n%
\\usepackage[asterism]{sectionbreak}\n%
\\sectionbreakmark{❦}\n\n\\usepackage{changepage}\n\\usepackage{algorithm}\n\\usepackage{pdfpages}\n\\usepackage{amsmath}\n\\usepackage{ifxetex}\n\\usepackage{setspace}\n\\ifxetex\n\\usepackage{fontspec,xltxtra,xunicode}\n\\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}\n\\setromanfont{Garamond
Premier Pro}\n \\setsansfont{TeX Gyre Pagella}\n  \\setmonofont{TeX Gyre
Heros}\n\n\\else\n  \\usepackage[mathletters]{ucs}\n
 \\usepackage[utf8x]{inputenc}\n\\fi\n\\usepackage{url}\n\\usepackage{paralist}\n\\usepackage{tikz}\n\\usepackage{calc}\n\\usepackage{eso-pic}\n\\usepackage{etoolbox}\n\\usepackage{xcolor}\n\\PassOptionsToPackage{hyperref,x11names}{xcolor}\n\\definecolor{pinterestred}{HTML}{C92228}\n\\definecolor{ulyssesbutterflyblue}{HTML}{1464F4}\n\\definecolor{signalflare}{HTML}{FB782C}\n\\definecolor{niceorange}{HTML}{77CC6D}\n\\definecolor{highlighteryellow}{HTML}{FFFF01}\n\\definecolor{ghostlygrey}{HTML}{000000}\n\\definecolor{firstcolor}{HTML}{00ADEF}\n\\definecolor{secondcolor}{HTML}{DD3E74}\n\\definecolor{periodblue}{HTML}{12239e}\n\\definecolor{denimblue}{HTML}{3A5F90}\n\\definecolor{electricblue}{HTML}{05ADF3}\n\\definecolor{resonateblue}{HTML}{005778}\n\\definecolor{resonateorange}{HTML}{da7635}\n\\definecolor{resonategrey}{HTML}{4d4d4c}\n\\definecolor{nliblue}{HTML}{2f9ed3}\n\\definecolor{elegantblue}{HTML}{4380b9}\n\\definecolor{spacegrey}{HTML}{434346}\n\n\\newtoks\\leftheader\n\\newtoks\\leftheaderurl\n\\newtoks\\coverimage\n\n\n\n%
\\usepackage{magaz}\n\n\n%Define Bold
face\n\\DeclareTextFontCommand{\\textbf}{\\sffamily\\bfseries}\n\\DeclareTextFontCommand{\\textit}{\\itshape}\n\n\\usepackage{microtype}
%  Improve the overall typography and appearance of your document by
enabling micro-typographic features, such as character protrusion and font
expansion:\n\n\n\\hyphenpenalty=1000\n\\tolerance=1000\n\\exhyphenpenalty=100\n\\pretolerance=150\n\\emergencystretch=10pt\n\n\n\n\\pagenumbering{arabic}\n\\makeatletter\n\n\n\n\\setcounter{secnumdepth}{0}\n\n\n\\usepackage[font={small,tt}]{caption}\n\n\\usepackage{booktabs}
% Customized table styles: If you plan to use tables in your document, you
might want to consider customizing their appearance with the `booktabs`
package for professional-looking tables\n\n% Use the fancyhdr package to
customize the headers and footers of your document for a professional
appearance\n\n\\usepackage{fancyhdr}\n\\fancyhf{} % sets both header and
footer to
nothing\n\\renewcommand{\\headrulewidth}{0pt}\n\\pagestyle{fancy}\n\n\n%
doesn't work\n% source:
https://tex.stackexchange.com/questions/236705/how-do-i-show-the-subsection-name-and-the-subsubsection-number-and-name-in-a-fan\n%
https://tex.stackexchange.com/questions/310046/fancyhdr-and-redefinition-of-leftmark-rightmark\n%\\usepackage{blindtext}\n%\\let\\Sectionmark\\sectionmark\n%\\def\\sectionmark#1{\\def\\Sectionname{#1}\\Sectionmark{#1}}\n%\\let\\Subsectionmark\\subsectionmark\n%\\def\\subsectionmark#1{\\def\\Subsectionname{#1}\\Subsectionmark{#1}}\n%\\let\\Subsubsectionmark\\subsubsectionmark\n%\\def\\subsubsectionmark#1{\\def\\Subsubsectionname{#1}\\Subsubsectionmark{#1}}\n\n\n%
\\fancyhf{}\n% \\fancyhead[L]{\\thesection.\\ \\Sectionname} % displays the
section (1. SECTION NAME)\n% \\fancyhead[R]{\\thesubsection.\\
\\Subsectionname} % displays the subsection (1.1 SUBSECTION NAME)\n%
\\fancyfoot[R]{\\thesubsubsection.\\
\\Subsubsectionname}\n\n\n\n\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}\n\\lhead{\\scshape\\href{\\the\\leftheaderurl}{\\the\\leftheader}}\n\\chead{}\n\\rhead{{\\scshape{\\leftmark}}}
% Add section heading\n% \\rhead{\\@title:
{{\\leftmark}}}\n\\lfoot{}\n\\cfoot{\\thepage} % Add page
numbers\n\\rfoot{}\n\n\n% Ensure consistent spacing after periods in your
document by using the xspace
package:\n\\usepackage{xspace}\n\n\\newenvironment{fauxsubtitle}\n{\n\n\\Large\n\\itshape\n}\n\n\n\n\n\\usepackage{listings}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{12pt
plus 2pt minus 1pt} % space between paragraphs\n\n% spacing: how to read
{12pt plus 4pt minus 2pt}\n%           12pt is what we would like the
spacing to be\n%           plus 4pt means that TeX can stretch it by at
most 4pt\n%           minus 2pt means that TeX can shrink it by at most
2pt\n%       This is one example of the concept of, 'glue', in
TeX\n\n\n\\usepackage{setspace}\n\\onehalfspacing\n\\setstretch{1.2}\n\n\\usepackage{fancyvrb}\n\\usepackage{enumerate}\n\\usepackage{ctable}\n\\setlength{\\paperwidth}{8.5in}\n\\setlength{\\paperheight}{11in}\n\\usepackage{tocloft}\n\\renewcommand{\\cftsecleader}{\\cftdotfill{\\cftdotsep}}\n\\usepackage[normalem]{ulem}\n\n\n\\makeatletter\n\\newcommand{\\globalcolor}[1]{%\n
 \\color{#1}\\global\\let\\default@color\\current@color\n}\n\\makeatother\n\n\\newcommand{\\textsubscr}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}\n\n\\usepackage{enumitem}\n\n\\newlist{mylist}{enumerate}{10}\n\n\n%
control line spacing in bulleted list\n\\setlist{noitemsep, topsep=-8pt,
after=\\vspace{12pt}} % for no spacing between list items\n% see:
https://tex.stackexchange.com/questions/199118/modifying-whitespace-before-and-after-list-separately-using-enumitem-package\n%\\setlist{topsep=0pt}
% for a line between list items\n\n\n\\renewcommand{\\labelitemi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemviii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemix}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemx}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\n\\setlistdepth{10}\n\\setlist[itemize,1]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,2]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,3]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,4]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,5]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,6]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,7]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,8]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,9]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,10]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\renewlist{itemize}{itemize}{10}\n\n\n\\renewcommand{\\contentsname}{Table
of Contents}\n\n\n\n\\renewcommand{\\descriptionlabel}[1]{%\n
{\\hspace{\\labelsep}\\bfseries\\textsc{#1}}}\n\n\n\\setlist[description]{style=nextline,
before=\\vspace{\\baselineskip}}\n\n\n\\definecolor{azure}{HTML}{f2feff}\n\n\\usepackage{tikz}\n\\usetikzlibrary{backgrounds}\n\\makeatletter\n\n\\tikzset{%\n
 fancy quotes/.style={\n    text width=\\fq@width pt,\n    align=justify,\n
   inner sep=1em,\n    anchor=north west,\n    minimum width=\\linewidth,\n
 },\n  fancy quotes width/.initial={.8\\linewidth},\n  fancy quotes
marks/.style={\n    scale=8,\n    text=black,\n    inner sep=0pt,\n  },\n
 fancy quotes opening/.style={\n    fancy quotes marks,\n  },\n  fancy
quotes closing/.style={\n    fancy quotes marks,\n  },\n  fancy quotes
background/.style={\n    show background rectangle,\n    inner frame
xsep=0pt,\n    background rectangle/.style={\n      fill=azure,\n
 rounded corners,\n    },\n
 }\n}\n\n\\newenvironment{fancyquotes}[1][]{%\n\\noindent\n\\tikzpicture[fancy
quotes background]\n\\node[fancy quotes opening,anchor=north west] (fq@ul)
at (0,0) {``};\n\\tikz@scan@one@point\\pgfutil@firstofone(fq@ul.east
)\n\\pgfmathsetmacro{\\fq@width}{\\linewidth - 2*\\pgf@x}\n\\node[fancy
quotes,#1] (fq@txt) at (fq@ul.north west)
\\bgroup}\n{\\egroup;\n\\node[overlay,fancy quotes closing,anchor=east] at
(fq@txt.south east)
{''};\n\\endtikzpicture}\n\\makeatother\n\n%\\setlength{\\intextsep}{10pt
plus 1.0pt minus 2.0pt}\n\n\n\\newenvironment{indentedsection}\n{
 {\\adjustwidth{2em}{0pt}}\n
 {\\endadjustwidth}\n}\n\n\\usepackage{setspace}\n\\usepackage{lipsum}\n\\usepackage{etoolbox}\n\\AtBeginEnvironment{quote}{\\singlespace\\vspace{-\\topsep}\\small}\n\\AtEndEnvironment{quote}{\\vspace{-\\topsep}\\endsinglespace}\n\n\n\\usepackage[sc]{titlesec}\n\n\n\n\\newlength\\TitleOverhang\n\\setlength\\TitleOverhang{1.5cm}\n\n\\newcommand\\Overhang[1]{%\n
\\llap{\\makebox[\\TitleOverhang][l]{#1}}%\n}\n\n\n%
\\titlespacing{command}{left spacing}{before spacing}{after
spacing}[right]\n\\titlespacing*{\\section}{0pt}{150pt}{40pt}\n%\\titlespacing*{\\subsection}{0pt}{0pt}{-6pt}\n\\titlespacing*{\\subsubsection}{0pt}{16pt}{0pt}\n\n\\titlespacing{\\paragraph}{0pt}{0pt}{.5em}[]\n\n\n\\titleformat*{\\section}{\\ttfamily\\scshape\\fontsize{40}{36}\\raggedleft\\ttfamily\\color{spacegrey}}\n\\titleformat*{\\subsection}{\\sffamily\\setstretch{0.1}\\fontsize{24}{36}\\raggedright\\sffamily}\n\\titleformat*{\\subsubsection}{\\ttfamily\\scshape\\fontsize{18}{16}\\raggedright\\ttfamily}\\color{spacegrey}\n\n\\titleformat*{\\paragraph}{\\ttfamily\\bfseries\\fontsize{19}{12}\\raggedright}\n\\titleformat*{\\subparagraph}{\\sffamily\\fontsize{16}{12}\\raggedright\\ttfamily\\bfseries}\n\n\\DeclareTextFontCommand{\\nonsection}{\\sffamily\\fontsize{19}{19}\\raggedright\\sffamily\\textlf}\n\n\\DeclareTextFontCommand{\\nonsubsection}{\\sffamily\\itshape\\fontsize{18}\\raggedright\\sffamily}\n\n\\DeclareTextFontCommand{\\nonsubsubsection}{\\sffamily\\fontsize{18}\\raggedright\\sffamily}\n\n\\newenvironment{tagline}%
environment name\n{% begin
code\n\\vspace{-36pt}\n\\Large\n\\begin{itshape}%\n
 \\par\\vspace{\\baselineskip}\\noindent\\ignorespaces\n}%\n{% end code\n
 \\end{itshape}\\vspace{24pt}\\ignorespacesafterend\n}\n\n\n\n\\newenvironment{fauxtitle}%
environment name\n{% begin
code\n%\\vspace{12pt}\n\\Large\n\\begin{bfseries}%\n
 \\par\\vspace{\\baselineskip}\\noindent\\ignorespaces\n}%\n{% end code\n
 \\end{bfseries}\\vspace{12pt}\\ignorespacesafterend\n}\n\n\n\n\\newenvironment{fauxcenter}%
environment name\n{% begin code\n\n\\Large\n\\begin{center}\n\n}%\n{% end
code\n\\end{center}\\ignorespacesafterend\n}\n\n\n\n\n\\newenvironment{causationstatement}%
environment name\n{% begin
code\n\\vspace{-30pt}\n\\ttfamily\n\\bfseries\n\\begin{center}\n\n}%\n{%
end
code\n\\end{center}\\ignorespacesafterend\n}\n\n\n\n\n\n\n\\usepackage[breaklinks=true,linktocpage,xetex]{hyperref}\n\\hypersetup{colorlinks,
citecolor=elegantblue,filecolor=elegantblue,linkcolor=elegantblue,urlcolor=elegantblue}\n\n\\renewcommand\\maketitle{}\n\n\n\n
     [NO-DEFAULT-PACKAGES]\n      [NO-PACKAGES]"
                      ("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" .
"\\subsubsection*{%s}")
                      ("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
                     ("elegant"

"\n\n\\documentclass[12pt]{article}\n\\usepackage[includeheadfoot,margin=1.5in,hmargin=1.5in,vmargin=0.5in]{geometry}
% for normal
margins\n\n\\linespread{1.2}\n\n\n\\usepackage{float}\n\\usepackage{changepage}\n\n\\usepackage{wrapfig}\n\n\\usepackage{algorithm}\n\\usepackage{amsmath}\n\\usepackage{ifxetex}\n\\ifxetex\n
 \\usepackage{fontspec,xltxtra,xunicode}\n
 \\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}\n\n% define
Helvetica Now font weights\n\\setmainfont{EBGaramond}[\n  Path =
/Users/jay/Library/Fonts/,\n%        UprightFont =
HelveticaNowText-Light,\n        UprightFont = SF-Pro-Text-Light,\n
 BoldFont = HelveticaNowDisplay-Light,\n        ItalicFont =
HelveticaNowText-LightItalic,\n        BoldItalicFont =
HelveticaNowDisplay-BoldIta,\n  Extension =
.ttf\n\n\\setromanfont{HelveticaNowText-Light}\n\n% \\setromanfont{sf
Pro}\n% not sure i like
this\n\n\\setsansfont{HelveticaNowDisplay-Regular}\n\\newfontfamily{\\thindisplayfont}{HelveticaNowDisplay-Light}\n\n
 \\setmonofont{Myriad Pro}\n\\else\n  \\usepackage[mathletters]{ucs}\n
 \\usepackage[utf8x]{inputenc}\n\\fi\n\n\\usepackage[obeyspaces]{url}\n\\PassOptionsToPackage{obeyspaces}{url}\n\n\\usepackage{paralist}\n\\usepackage{graphicx}\n\\setkeys{Gin}{resolution=72}\n\\usepackage{tikz}\n%
\\usepackage[asterism]{sectionbreak}\n\\usepackage{calc}\n\\usepackage{eso-pic}\n\\usepackage{etoolbox}\n\\usepackage{xcolor}\n\\PassOptionsToPackage{hyperref,x11names}{xcolor}\n\\definecolor{pinterestred}{HTML}{C92228}\n\\definecolor{ulyssesbutterflyblue}{HTML}{1464F4}\n\\definecolor{signalflare}{HTML}{FB782C}\n\\definecolor{niceorange}{HTML}{77CC6D}\n\\definecolor{highlighteryellow}{HTML}{FFFF01}\n\\definecolor{ghostlygrey}{HTML}{000000}\n\\definecolor{firstcolor}{HTML}{00ADEF}\n\\definecolor{secondcolor}{HTML}{DD3E74}\n\\definecolor{periodblue}{HTML}{12239e}\n\\definecolor{denimblue}{HTML}{3A5F90}\n\\definecolor{electricblue}{HTML}{05ADF3}\n\\definecolor{resonateblue}{HTML}{005778}\n\\definecolor{resonateorange}{HTML}{da7635}\n\\definecolor{resonategrey}{HTML}{4d4d4c}\n\\definecolor{nliblue}{HTML}{2f9ed3}\n%\\definecolor{dullerelegantblue}{HTML}{4380b9}\n%\\definecolor{elegantblue}{HTML}{1792d1}\n\\definecolor{ideablue}{HTML}{55C1E7}\n\n\n\\newtoks\\leftheader\n\\newtoks\\leftheaderurl\n\\newtoks\\coverimage\n\n\\raggedright\n\\hyphenpenalty=5000\n\\tolerance=1000\n\n%This
macro is to make cleaner the specification of the titling
font\n\\newfontfamily\\mytitlefont[Color={highlighteryellow}]{Arial}\n\\newfontfamily\\myauthorfont[Color={highlighteryellow}]{Arial}\n\\newfontfamily\\mybluefont[Color=elegantblue]{Arial}\n\n%Define
Bold
face\n\\DeclareTextFontCommand{\\textbf}{\\sffamily\\bfseries}\n\\DeclareTextFontCommand{\\textit}{\\itshape}\n\n\\usepackage{textcase}\n\n\\pagenumbering{arabic}\n\\makeatletter\n\n\n\\renewcommand{\\contentsname}{Table
of
Contents}\n\n\\setcounter{secnumdepth}{0}\n\n\n\\usepackage[labelformat=empty]{caption}\n\n\\usepackage{fancyhdr}\n\\pagestyle{fancy}\n\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}\n\\lhead{\\href{\\the\\leftheaderurl}{\\the\\leftheader}}\n\\chead{}\n\\rhead{{\\nouppercase{\\leftmark}}}\n%
\\rhead{\\@title: {\\nouppercase{\\leftmark}}}\n\n\\lhead{\\@title}}} %
title of the document as left
header\n\n\n\\lfoot{}\n\\cfoot{\\thepage}\n\\rfoot{}\n\\usepackage{listings}\n\\setlength{\\parindent}{0pt}\n\\setlength{\\parskip}{12pt
plus 2pt minus 1pt} % space between paragraphs\n\n% spacing: how to read
{12pt plus 4pt minus 2pt}\n%           12pt is what we would like the
spacing to be\n%           plus 4pt means that TeX can stretch it by at
most 4pt\n%           minus 2pt means that TeX can shrink it by at most
2pt\n%       This is one example of the concept of, 'glue', in
TeX\n\n\\usepackage{fancyvrb}\n\\usepackage{enumerate}\n\\usepackage{ctable}\n\\setlength{\\paperwidth}{8.5in}\n\\setlength{\\paperheight}{11in}\n
 \\tolerance=1000\n\\usepackage{tocloft}\n\\renewcommand{\\cftsecleader}{\\cftdotfill{\\cftdotsep}}\n\\usepackage[normalem]{ulem}\n\n\n\\makeatletter\n\\newcommand{\\globalcolor}[1]{%\n
 \\color{#1}\\global\\let\\default@color\\current@color\n}\n\\makeatother\n\n\\newcommand{\\textsubscr}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}\n\n\\usepackage{enumitem}\n\n\\newlist{mylist}{enumerate}{10}\n\n\n%
control line spacing in bulleted list\n\\setlist{noitemsep, topsep=-8pt,
after=\\vspace{12pt}} % for no spacing between list items\n% see:
https://tex.stackexchange.com/questions/199118/modifying-whitespace-before-and-after-list-separately-using-enumitem-package\n%\\setlist{topsep=0pt}
% for a line between list items\n\n\n\\renewcommand{\\labelitemi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemiv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemv}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvi}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemvii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemviii}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemix}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\\renewcommand{\\labelitemx}{\\raise
0.25ex\\hbox{\\tiny$\\bullet$}}\n\n\\setlistdepth{10}\n\\setlist[itemize,1]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,2]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,3]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,4]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,5]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,6]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,7]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,8]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,9]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\setlist[itemize,10]{label=\\raise
0.25ex\\hbox\\tiny$\\bullet$}\n\\renewlist{itemize}{itemize}{10}\n\n\n\n\n\n\\definecolor{azure}{HTML}{f2feff}\n\n\\usepackage{lipsum}\n\\usepackage{tikz}\n\\usetikzlibrary{backgrounds}\n\\makeatletter\n\n\\tikzset{%\n
 fancy quotes/.style={\n    text width=\\fq@width pt,\n    align=justify,\n
   inner sep=1em,\n    anchor=north west,\n    minimum width=\\linewidth,\n
 },\n  fancy quotes width/.initial={.8\\linewidth},\n  fancy quotes
marks/.style={\n    scale=8,\n    text=black,\n    inner sep=0pt,\n  },\n
 fancy quotes opening/.style={\n    fancy quotes marks,\n  },\n  fancy
quotes closing/.style={\n    fancy quotes marks,\n  },\n  fancy quotes
background/.style={\n    show background rectangle,\n    inner frame
xsep=0pt,\n    background rectangle/.style={\n      fill=azure,\n
 rounded corners,\n    },\n
 }\n}\n\n\\newenvironment{fancyquotes}[1][]{%\n\\noindent\n\\tikzpicture[fancy
quotes background]\n\\node[fancy quotes opening,anchor=north west] (fq@ul)
at (0,0) {``};\n\\tikz@scan@one@point\\pgfutil@firstofone(fq@ul.east
)\n\\pgfmathsetmacro{\\fq@width}{\\linewidth - 2*\\pgf@x}\n\\node[fancy
quotes,#1] (fq@txt) at (fq@ul.north west)
\\bgroup}\n{\\egroup;\n\\node[overlay,fancy quotes closing,anchor=east] at
(fq@txt.south east)
{''};\n\\endtikzpicture}\n\\makeatother\n\n%\\setlength{\\intextsep}{10pt
plus 1.0pt minus 2.0pt}\n\n\\newenvironment{indentedsection}\n
 {\\adjustwidth{2em}{0pt}}\n
 {\\endadjustwidth}\n\n\n\\usepackage{setspace}\n\\usepackage{lipsum}\n\\usepackage{etoolbox}\n\\AtBeginEnvironment{quote}{\\singlespace\\vspace{-\\topsep}\\small}\n\\AtEndEnvironment{quote}{\\vspace{-\\topsep}\\endsinglespace}\n\n\n\\usepackage[sc]{titlesec}\n\n\n\\newlength\\TitleOverhang\n\\setlength\\TitleOverhang{1.5cm}\n\n\\newcommand\\Overhang[1]{%\n
\\llap{\\makebox[\\TitleOverhang][l]{#1}}%\n}\n\n\n%
\\titlespacing{command}{left spacing}{before spacing}{after
spacing}[right]\n%\\titlespacing*{\\section}{0pt}{16pt}{-6pt}\n%\\titlespacing*{\\subsection}{0pt}{16pt}{-6pt}\n%\\titlespacing*{\\subsubsection}{0pt}{16pt}{-6pt}\n\n%
\\titlespacing{command}{left spacing}{before spacing}{after
spacing}[right]\n\\titlespacing*{\\section}{1.5ex}{24pt}{6pt}\n\\titlespacing*{\\subsection}{0pt}{0pt}{-6pt}\n\\titlespacing*{\\subsubsection}{0pt}{0pt}{-12pt}\n\n\n\\titleformat*{\\section}{\\sffamily\\bfseries\\fontsize{30}{20}\\raggedright\\sffamily\\scshape\\color{ideablue}}\n\\titleformat*{\\subsection}{\\sffamily\\bfseries\\fontsize{18}{15}\\raggedright\\scshape\\color{black}}\n\\titleformat*{\\subsubsection}{\\sffamily\\bfseries\\fontsize{14}{16}\\raggedright\\sffamily\\color{ideablue}}\n\\titleformat*{\\paragraph}{\\sffamily\\fontsize{13}{12}\\raggedright\\bfseries\\color{black}}\n\\titleformat*{\\subparagraph}{\\sffamily\\fontsize{14}{14}\\raggedright\\bfseries\\ttfamily\\color{ideablue}}\n\n\n\\DeclareTextFontCommand{\\nonsection}{\\thindisplayfont\\fontsize{19}{19}\\raggedright\\thindisplayfont\\textlf\\color{ideablue}
}\n\n\\DeclareTextFontCommand{\\nonsubsection}{\\thindisplayfont\\fontsize{18}{15}\\raggedright\\scshape\\color{ideablue}}\n\n\\DeclareTextFontCommand{\\nonsubsubsection}{\\thindisplayfont\\itshape\\fontsize{14}{14}\\raggedright\\sffamily\\color{ideablue}
}\n\n\n\\usepackage[breaklinks=true,linktocpage,xetex]{hyperref}\n\\hypersetup{colorlinks,
citecolor=ideablue,filecolor=ideablue,linkcolor=ideablue,urlcolor=ideablue}\n\n\\renewcommand\\maketitle{}\n\n\n
     [NO-DEFAULT-PACKAGES]\n      [NO-PACKAGES]"
                      ("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" .
"\\subsubsection*{%s}")
                      ("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
                     ("my-letter"
                      "\\documentclass[%\n DIV=14,\n fontsize=12pt,\n
parskip=half,\n subject=titled,\n backaddress=false,\n fromalign=left,\n
fromemail=true,\n fromphone=true]{scrlttr2}\n [DEFAULT-PACKAGES]\n
[PACKAGES]\n [EXTRA]")
                     ("article" "\\documentclass[11pt]{article}"
("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" .
"\\subsection*{%s}")
                      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
                     ("report" "\\documentclass[11pt]{report}"
("\\part{%s}" . "\\part*{%s}") ("\\chapter{%s}" . "\\chapter*{%s}")
                      ("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" .
"\\subsubsection*{%s}"))
                     ("book" "\\documentclass[11pt]{book}" ("\\part{%s}" .
"\\part*{%s}") ("\\chapter{%s}" . "\\chapter*{%s}")
                      ("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" .
"\\subsubsection*{%s}"))
                     )
 org-n-level-faces 9
 org-ai-on-project-mode-hook '(#[0 "\301\300!\210\302\211%10\207"
[show-trailing-whitespace make-local-variable nil] 2])
 org-twbs-head-include-scripts nil
 org-highlight-latex-and-related '(latex)
 org-odt-format-headline-function 'org-odt-format-headline-default-function
 org-use-speed-commands t
 org-timeline-source-url "/Users/jay/Dropbox/github/
incandescentman.github.io/timeline/dist"
 org-protocol-protocol-alist '(("org-roam-node" :protocol "roam-node"
:function org-roam-protocol-open-node)
                               ("org-roam-ref" :protocol "roam-ref"
:function org-roam-protocol-open-ref)
                               ("org-roam-node" :protocol "roam-node"
:function org-roam-protocol-open-node)
                               ("org-roam-ref" :protocol "roam-ref"
:function org-roam-protocol-open-ref))
 org-roam-capture-preface-hook '(org-roam-dailies--override-capture-time-h
org-roam-capture--try-capture-to-ref-h)
 org-extend-today-until 8
 org-html-checkbox-type 'unicode
 org-list-demote-modify-bullet '(("+" . "-") ("-" . "+"))
 org-link-translation-function 'toc-org-unhrefify
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-capture-prepare-finalize-hook '(org-roam-capture--install-finalize-h)
 org-src-preserve-indentation t
 org-odt-convert-processes '(("LibreOffice"
"/Applications/LibreOffice.app/Contents/MacOS/soffice --headless
--convert-to %f%x --outdir %d %i"))
 org-roam-preview-function 'org-roam-preview-default-function
 org-src-mode-hook '(org-src-babel-configure-edit-buffer
org-src-mode-configure-edit-buffer)
 org-roam-db-autosync-mode t
 org-checkbox-statistics-hook '(ndk/checkbox-list-complete)
 org-confirm-elisp-link-function 'yes-or-no-p
 org-cycle-separator-lines 0
 org-twbs-head-include-default-style nil
 org-superstar-headline-bullets-list '(42 42 42 42)
 org-log-buffer-setup-hook '(org-roam-log--setup spacemacs//org-note-mode)
 org-clock-report-include-clocking-task t
 org-safe-remote-resources '("\\`https://fniessen
\\.github\\.io/org-html-themes/org/theme-bigblow\\.setup\\'")
 org-insert-mode-line-in-empty-file t
 org-hide-leading-stars t
 org-twbs-format-headline-function 'ignore
 org-clock-idle-time 30
 org-todo-keywords '((sequence "TODO" "STARTED" "|" "DONE") (sequence
"MISSED" "|" "DONE") (sequence "NEED TO INVOICE" "INVOICED" "|" "PAID")
                     (sequence "REWARD" "|" "REWARDED") (sequence "TO
PROCESS" "|" "PROCESSED"))
 org-twbs-postamble-format nil
 org-mime-src-mode-hook '(org-mime-src-mode-configure-edit-buffer)
 org-latex-logfiles-extensions '("lof" "lot" "tex" "odt" "aux" "idx" "log"
"out" "toc" "nav" "snm" "vrb" "dvi" "fdb_latexmk" "blg" "brf" "fls" "entoc"
"ps"
                                 "spl" "bbl")
 org-roam-capture-new-node-hook '(org-roam-capture--insert-captured-ref-h)
 org-export-with-timestamps 'active
 org-support-shift-select 'always
 org-structure-template-alist '(("a" . "export ascii") ("c" . "center")
("C" . "comment") ("e" . "example") ("x" . "example") ("le" . "example")
                                ("E" . "export") ("h" . "export html") ("l"
. "src emacs-lisp") ("el" . "src emacs-lisp") ("la" . "export latex")
                                ("q" . "quote") ("s" . "src") ("sh" . "src
sh") ("f" . "example fountain") ("v" . "example verse"))
 org-blocker-hook '(org-block-todo-from-checkboxes
org-block-todo-from-children-or-siblings-or-parent)
 org-html-text-markup-alist '((bold . "<strong>%s</strong>") (code .
"<code>%s</code>") (italic . "<em>%s</em>") (strike-through .
"<del>%s</del>")
                              (underline . "<span
class=\"underline\">%s</span>") (verbatim . "<code>%s</code>"))
 org-speed-command-hook '(org-speed-command-activate
org-babel-speed-command-activate)
 org-html-format-inlinetask-function
'org-html-format-inlinetask-default-function
 org-clock-persist-file "~/.emacs.d/.cache/org-clock-save.el"
 org-ascii-format-inlinetask-function 'org-ascii-format-inlinetask-default
 org-latex-default-class "elegant"
 org-latex-prefer-user-labels t
 org-odt-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME CONTENTS)"]
 org-html-metadata-timestamp-format "%m-%d %a %H:%M"
 org-enforce-todo-dependencies t
 org-fold-core-isearch-open-function 'org-fold-core--isearch-reveal
 org-export-with-smart-quotes t
 org-clock-in-resume t
 org-pomodoro-finished-hook '((lambda nil
                               (do-applescript
                                (format
                                 "\nignoring application responses\n tell
application \"System Events\"\nkeystroke \"P\" using {command down, shift
down, option down, control down} -- start Pomodoro One\nkey code {118}\nend
tell\nend ignoring\n\n\nset now to current date\nset nowTime to (hours of
now) & \":\" & (minutes of now)\nset pomodoroStart to (current date) - 25 *
minutes\nset pStartTime to (hours of pomodoroStart) & \":\" & (minutes of
pomodoroStart)\nset achieved to text returned of (display dialog \"What did
you achieve in this Pomodoro?\" default answer \"\")\nset entry_text to \"#
Bookwriting:\" & pStartTime & \" - \" & time string of now & \"\n\n\" &
achieved & \"\n\n#pomodoro \"\n\ndo shell script \"echo \" & (quoted form
of entry_text) & \" | /usr/local/bin/dayone new\"\n\n\n")
                                )
                               )
                              )
 org-M-RET-may-split-line '((item . t))
 org-clock-persist t
 org-latex-format-inlinetask-function
'org-latex-format-inlinetask-default-function
 org-persist-before-write-hook '(org-element--cache-persist-before-write)
 org-emphasis-alist '(("*" bold) ("/" italic) ("_" underline) ("~" org-code
verbatim) ("=" flyspell-incorrect) ("+" (:strike-through t)))
 org-tab-first-hook '(yas-org-very-safe-expand
org-babel-hide-result-toggle-maybe org-babel-header-arg-expand)
 org-export-with-toc nil
 org-link-shell-confirm-function 'yes-or-no-p
 org-display-custom-times t
 org-babel-pre-tangle-hook '(save-buffer)
 org-superstar-remove-leading-stars t
 org-roam-completion-everywhere t
 org-agenda-loop-over-headlines-in-active-region nil
 org-fontify-quote-and-verse-blocks t
 org-attach-id-dir "/Users/jay/Dropbox/roam/attachments"
 org-clock-auto-clock-resolution t
 org-todo-keyword-faces '(("PROCESSED" :foreground "LavenderBlush"
:background "darkgrey" :weight bold)
                          ("NEXT" :background "medium sea green"
:foreground "white" :weight bold) ("ACTION" :foreground "medium sea green"
:weight bold)
                          ("WAITING" :background "yellow" :foreground
"purple" :weight bold) ("EVENT" :background "gray25" :foreground "white"
:weight bold)
                          ("PROJECT" :background "firebrick" :foreground
"white" :weight bold)
                          ("STARTED" :background "dodger blue" :foreground
"white" :weight bold)
                          ("DONE" :background "white" :foreground "black"
:weight bold))
 org-export-format-drawer-function 'jbd-org-export-format-drawer
 org-capture-mode-hook '(spacemacs//org-capture-start writeroom-mode
delete-other-windows turn-on-auto-capitalize-mode)
 org-roam-mode-sections '(org-roam-backlinks-section
org-roam-reflinks-section org-roam-unlinked-references-section)
 org-occur-hook '(org-first-headline-recenter)
 org-roam-log-setup-hook '(org-roam--register-completion-functions-h)
 org-latex-image-default-width "370pt"
 org-html-head-include-default-style nil
 org-export-with-drawers t
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-html-html5-fancy t
 org-treat-S-cursor-todo-selection-as-state-change nil
 org-roam-node-annotation-function 'org-roam-node-read--annotation
 org-odt-preferred-output-format "docx"
 org-link-parameters '(("message" :follow org-mac-link-mail-open)
("x-devonthink-item" :follow org-mac-link-devonthink-item-open)
                       ("mac-evernote" :follow
org-mac-link-evernote-note-open) ("mac-outlook" :follow
org-mac-link-outlook-message-open)
                       ("acrobat" :follow org-mac-link-acrobat-open)
("skim" :follow org-mac-link-skim-open)
                       ("addressbook" :follow
org-mac-link-addressbook-item-open) ("x-together-item" :follow
org-mac-link-together-item-open)
                       ("roam" :follow org-roam-link-follow-link)
("attachment" :follow org-attach-follow :complete org-attach-complete-link)
                       ("yt" :follow (lambda (handle) (browse-url (concat "
https://www.youtube.com/embed/" handle))) :export
                        (lambda (path desc backend)
                         (cond ((eql backend 'html) (format
yt-iframe-format path (or desc "")))
                          ((eql backend 'latex) (format "href{%s}{%s}" path
(or desc "video"))))
                         )
                        )
                       ("info" :follow org-info-open :export
org-info-export :store org-info-store-link :insert-description
org-info-description-as-command)
                       ("id" :follow org-roam-id-open) ("hook" :follow
my/hook :export nil) ("file+sys") ("file+emacs")
                       ("shell" :follow org-link--open-shell) ("news"
:follow #[514 "\301\300\302%4Q%2\"\207" ["news" browse-url ":"] 6 "\n\n(fn
URL ARG)"])
                       ("mailto" :follow #[514 "\301\300\302%4Q%2\"\207"
["mailto" browse-url ":"] 6 "\n\n(fn URL ARG)"])
                       ("https" :follow #[514 "\301\300\302%4Q%2\"\207"
["https" browse-url ":"] 6 "\n\n(fn URL ARG)"])
                       ("http" :follow #[514 "\301\300\302%4Q%2\"\207"
["http" browse-url ":"] 6 "\n\n(fn URL ARG)"])
                       ("ftp" :follow #[514 "\301\300\302%4Q%2\"\207"
["ftp" browse-url ":"] 6 "\n\n(fn URL ARG)"])
                       ("help" :follow org-link--open-help :store
org-link--store-help) ("file" :complete org-link-complete-file)
                       ("elisp" :follow org-link--open-elisp))
 org-roam-ui-browser-function 'browse-url
 org-html-format-headline-function
'org-html-format-headline-default-function
 org-roam-capture-templates '(("n" "note" plain "- Links :: \n- Source ::
\n\n\n* ${title}\n- %?" :target
                               (file+head
"notes/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:note:") :unnarrowed t)
                              ("m" "memoir" plain "- Links :: \n- Source ::
\n\n* ${title}\n- %?" :target
                               (file+head
"memoir/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:memoir:") :unnarrowed t)
                              ("k" "kanban" plain "- Links :: \n- Source ::
\n\n* ${title}\n- %?" :target
                               (file+head
"kanban/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:kanban:") :unnarrowed t)
                              ("M" "mantra" plain "- Links :: \n- Source ::
\n\n* ${title}\n- %?" :target
                               (file+head
"mantras/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:mantras:") :unnarrowed t)
                              ("p" "person" plain "%?" :target
                               (file+head
"person/%<%Y%m%d%H%M%S>-${slug}.org"
                                "#+TITLE: ${title}\n#+FILETAGS: :person:\n-
Links :: \n- Source :: \n\n\n* ${title}\n- ")
                               :unnarrowed t)
                              ("b" "book" plain "- Links :: \n- Source ::
\n\n* ${title}\n- %?" :target
                               (file+head
"book/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS: :book:")
:unnarrowed t)
                              ("P" "Plans" plain "%?" :target
                               (file+head
"project/%<%Y%m%d%H%M%S>-${slug}.org"
                                "#+TITLE: ${title}\n#+FILETAGS:
:project:\n- Links :: \n- Source :: \n\n\n* ${title}\n- ")
                               :unnarrowed t)
                              ("x" "cuts" plain "- Links :: \n- Source ::
\n\n* ${title}\n- %?" :target
                               (file+head
"cuts/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS: :cuts:")
:unnarrowed t)
                              ("f" "finances and housekeeping" plain "-
Links :: \n- Source :: \n\n* ${title}\n- %?" :target
                               (file+head
"finances/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:finances:") :unnarrowed t)
                              ("F" "Food and recipes " plain "- Links ::
\n- Source :: \n\n* ${title}\n- %?" :target
                               (file+head
"food/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS: :food:")
:unnarrowed t)
                              ("l" "definition" plain "- Links :: \n-
Source :: \n\n* ${title}\n- %?" :target
                               (file+head
"definitions/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:definition:") :unnarrowed t)
                              ("s" "sentence" plain "- Links :: \n- Source
:: \n\n* ${title}\n- %?" :target
                               (file+head
"sentences/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:sentence:") :unnarrowed t)
                              ("i" "idea" plain "- Links :: \n- Source ::
\n\n* ${title}\n- %?" :target
                               (file+head
"ideas/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:idea:") :unnarrowed t)
                              ("c" "conversation" plain "- Links :: \n-
Source :: \n\n* ${title}\n- %?" :target
                               (file+head
"conversations/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:conversation:") :unnarrowed t)
                              ("d" "default" plain "- Links :: \n- Source
:: \n\n* ${title}\n- %?" :target
                               (file+head
"notes/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:note:") :unnarrowed t)
                              ("e" "emacs" plain "- Links :: \n- Source ::
\n\n* ${title}\n- %?" :target
                               (file+head
"emacs/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:emacs:") :unnarrowed t)
                              ("T" "temporary" plain "- Links :: \n- Source
:: \n\n* ${title}\n- %?" :target
                               (file+head
"temp/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS: :temp:")
:unnarrowed t)
                              ("t" "therapy" plain "- Links :: \n- Source
:: \n\n* ${title}\n- %?" :target
                               (file+head
"therapy/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS:
:therapy:") :unnarrowed t)
                              ("I" "Intelligence" plain "- Links :: \n-
Source :: \n\n\n* ${title}\n- %?" :target
                               (file+head "AI/%<%Y%m%d%H%M%S>-${slug}.org"
"#+TITLE: ${title}\n#+FILETAGS: :intelligence:") :unnarrowed t)
                              ("a" "article notes or books and articles"
plain "- Links :: \n- Source :: \n\n* ${title}\n- %?" :target
                               (file+head
"literature-notes/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE:
${title}\n#+FILETAGS: :literaturenote:") :unnarrowed t)
                              ("w" "work ie NLI" plain "%?" :target
                               (file+head
"nli-roam/%<%Y%m%d%H%M%S>-${slug}.org"
                                "#+TITLE: ${title}\n#+FILETAGS: :work:\n-
Links :: \n- Source :: \n\n\n* ${title}\n- ")
                               :unnarrowed t)
                              ("z" "zork" plain "- Links :: \nSource ::
\n\n\n* ${title}\n- %?" :target
                               (file+head (lambda nil (concat (read-string
"Enter file path: ") "/%<%Y%m%d%H%M%S>-${slug}.org"))
                                "#+TITLE: ${title}\n#+FILETAGS: :work:")
                               :unnarrowed t)
                              )
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-attach-auto-tag "ATTACHMENTS"
 org-refile-allow-creating-parent-nodes 'confirm
 org-agenda-restore-windows-after-quit t
 org-export-date-timestamp-format "%Y%m%d %I:%M%p"
 org-twbs-postamble nil
 org-use-fast-todo-selection t
 org-latex-text-markup-alist '((bold . "\\textbf{%s}") (code . verb)
(italic . "\\textit{%s}") (strike-through . "\\sout{%s}") (underline .
"\\uline{%s}"))
 org-priority-start-cycle-with-default nil
 org-latex-inline-image-rules '(("file" .
"\\.\\(pdf\\|jpeg\\|jpg\\|png\\|ps\\|eps\\|tikz\\|pgf\\|svg\\|gif\\)\\'"))
 org-blank-before-new-entry '((heading . always) (plain-list-item))
 org-indent-mode-turns-off-org-adapt-indentation nil
 org-imenu-depth 8
 org-footnote-define-inline t
 org-html-footnotes-section "<div id=\"footnotes\">\n<h2
class=\"footnotes\">%s </h2>\n<div id=\"footnote\">\n%s\n</div>\n</div>"
 org-clock-persist-query-resume nil
 org-latex-pdf-process '("xelatex -shell-escape -interaction nonstopmode
-output-directory %o %f"
                         "xelatex -shell-escape -interaction nonstopmode
-output-directory %o %f"
                         "xelatex -shell-escape -interaction nonstopmode
-output-directory %o %f")
 org-return-follows-link t
 org-outline-path-complete-in-steps nil
 org-special-ctrl-a/e t
 org-tags-column 40
 org-id-method 'ts
 org-tab-before-tab-emulation-hook '(org-tempo-complete-tag)
 org-superstar-item-bullet-alist '((42 . 183) (43 . 183) (45 . 183))
 org-roam-indirect-buffer-hook '(org-roam--register-completion-functions-h)
 org-clock-into-drawer nil
 org-list-indent-offset 1
 org-list-allow-alphabetical t
 org-twbs-link-home "http://jaydixit.com"
 org-ascii-table-use-ascii-art t
 )

[-- Attachment #2: Type: text/html, Size: 95023 bytes --]

^ permalink raw reply	[relevance 8%]

* Re: [patch] ox-latex.el: fix blank lines behavior in verse block
  @ 2023-08-17 20:17 23%                                   ` Juan Manuel Macías
  0 siblings, 0 replies; 200+ results
From: Juan Manuel Macías @ 2023-08-17 20:17 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode

[-- Attachment #1: Type: text/plain, Size: 1434 bytes --]

Ihor Radchenko writes:

> Thanks!
>
>> * (org-latex-verse-block): now the treatment of blank lines is
>> consistent with the syntax of the LaTeX `verse' environment, and the
>> one provided by the `verse' package. If the `:literal' attribute is
>> used, all blank lines are preserved and exported as
>
> Please use double space between sentences and start sentences with
> capital letter.
>
>> +- =:literal= :: With value t, all blank lines are preserved and
>> +  exported as =\vspace*{\baselineskip}=, including the blank lines
>> +  before or after contents.  Note that without the =:literal=
>> +  attribute, one or more blank lines between stanzas are exported as a
>> +  single blank line, and any blank lines before or after the content
>> +  are removed, which is more consistent with the syntax of the LaTeX
>> +  `verse' environment, and the one provided by the `verse' package.
>> +  If the =verse= package is loaded, the vertical spacing between all
>> +  stanzas can be controlled by the global length =\stanzaskip= (see
>> +  https://www.ctan.org/pkg/verse).
>
> s/`verse'/=verse=/
>   
> And you need to update `test-ox-latex/verse' test - it is currently failing.

Sorry for the typos... Here goes the corrected patch again, with the
updated test.

-- 
Juan Manuel Macías

https://juanmanuelmacias.com

https://lunotipia.juanmanuelmacias.com

https://gnutas.juanmanuelmacias.com

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-lisp-ox-latex.el-Add-the-literal-attribute-to-verse-.patch --]
[-- Type: text/x-patch, Size: 6513 bytes --]

From bd956aa947e080ef10aa851f339414dc1cda1baf Mon Sep 17 00:00:00 2001
From: Juan Manuel Macias <maciaschain@posteo.net>
Date: Mon, 14 Aug 2023 21:48:58 +0200
Subject: [PATCH] lisp/ox-latex.el: Add the `:literal' attribute to verse
 block.

* (org-latex-verse-block): Now the treatment of blank lines is
consistent with the syntax of the LaTeX `verse' environment, and the
one provided by the `verse' package.  If the `:literal' attribute is
used, all blank lines are preserved and exported as
`\vspace*{\baselineskip}', including the blank lines before or after
contents.  The rx code has been suggested by Ihor Radchenko, to
improve readability.

* doc/org-manual.org (Verse blocks in LaTeX export): The new feature
is documented.

* testing/lisp/test-ox-latex.el (test-ox-latex/verse): Updated.
---
 doc/org-manual.org            | 18 ++++++++++++++----
 lisp/ox-latex.el              | 36 ++++++++++++++++++++++++++---------
 testing/lisp/test-ox-latex.el |  8 ++++----
 3 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index e59efc417..ce0521dee 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -14425,10 +14425,10 @@ The LaTeX export backend converts horizontal rules by the specified
 #+cindex: verse blocks, in @LaTeX{} export
 #+cindex: @samp{ATTR_LATEX}, keyword
 
-The LaTeX export backend accepts four attributes for verse blocks:
-=:lines=, =:center=, =:versewidth= and =:latexcode=.  The three first
-require the external LaTeX package =verse.sty=, which is an extension
-of the standard LaTeX environment.
+The LaTeX export backend accepts five attributes for verse blocks:
+=:lines=, =:center=, =:versewidth=, =:latexcode= and =:literal=.  The
+three first require the external LaTeX package =verse.sty=, which is
+an extension of the standard LaTeX environment.
 
 - =:lines= :: To add marginal verse numbering.  Its value is an
   integer, the sequence in which the verses should be numbered.
@@ -14440,6 +14440,16 @@ of the standard LaTeX environment.
   verse.
 - =:latexcode= :: It accepts any arbitrary LaTeX code that can be
   included within a LaTeX =verse= environment.
+- =:literal= :: With value t, all blank lines are preserved and
+  exported as =\vspace*{\baselineskip}=, including the blank lines
+  before or after contents.  Note that without the =:literal=
+  attribute, one or more blank lines between stanzas are exported as a
+  single blank line, and any blank lines before or after the content
+  are removed, which is more consistent with the syntax of the LaTeX
+  `verse' environment, and the one provided by the =verse= package.
+  If the =verse= package is loaded, the vertical spacing between all
+  stanzas can be controlled by the global length =\stanzaskip= (see
+  https://www.ctan.org/pkg/verse).
 
 A complete example with Shakespeare's first sonnet:
 
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 31cad1dc4..d11e3befa 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -4116,10 +4116,11 @@ contextual information."
   (let* ((lin (org-export-read-attribute :attr_latex verse-block :lines))
          (latcode (org-export-read-attribute :attr_latex verse-block :latexcode))
          (cent (org-export-read-attribute :attr_latex verse-block :center))
+         (lit (org-export-read-attribute :attr_latex verse-block :literal))
          (attr (concat
-	        (if cent "[\\versewidth]" "")
-	        (if lin (format "\n\\poemlines{%s}" lin) "")
-	        (if latcode (format "\n%s" latcode) "")))
+		(if cent "[\\versewidth]" "")
+		(if lin (format "\n\\poemlines{%s}" lin) "")
+		(if latcode (format "\n%s" latcode) "")))
          (versewidth (org-export-read-attribute :attr_latex verse-block :versewidth))
          (vwidth (if versewidth (format "\\settowidth{\\versewidth}{%s}\n" versewidth) ""))
          (linreset (if lin "\n\\poemlines{0}" "")))
@@ -4128,20 +4129,37 @@ contextual information."
       verse-block
       ;; In a verse environment, add a line break to each newline
       ;; character and change each white space at beginning of a line
-      ;; into a space of 1 em.  Also change each blank line with
-      ;; a vertical space of 1 em.
+      ;; into a normal space, calculated with `\fontdimen2\font'.  One
+      ;; or more blank lines between lines are exported as a single
+      ;; blank line.  If the `:lines' attribute is used, the last
+      ;; verse of each stanza ends with the string `\\!', according to
+      ;; the syntax of the `verse' package. The separation between
+      ;; stanzas can be controlled with the length `\stanzaskip', of
+      ;; the aforementioned package.  If the `:literal' attribute is
+      ;; used, all blank lines are preserved and exported as
+      ;; `\vspace*{\baselineskip}', including the blank lines before
+      ;; or after CONTENTS.
       (format "%s\\begin{verse}%s\n%s\\end{verse}%s"
 	      vwidth
 	      attr
 	      (replace-regexp-in-string
-	       "^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m)))
+	       "^[ \t]+" (lambda (m) (format "\\hspace*{%d\\fontdimen2\\font}" (length m)))
 	       (replace-regexp-in-string
-                (concat "^[ \t]*" (regexp-quote org-latex-line-break-safe) "$")
-	        "\\vspace*{1em}"
+                (if (not lit)
+		    (rx-to-string
+                     `(seq (group ,org-latex-line-break-safe "\n")
+		           (1+ (group line-start (0+ space) ,org-latex-line-break-safe "\n"))))
+		  (concat "^[ \t]*" (regexp-quote org-latex-line-break-safe) "$"))
+	        (if (not lit)
+		    (if lin "\\\\!\n\n" "\n\n")
+		  "\\vspace*{\\baselineskip}")
 	        (replace-regexp-in-string
 	         "\\([ \t]*\\\\\\\\\\)?[ \t]*\n"
                  (concat org-latex-line-break-safe "\n")
-	         contents nil t)
+	         (if (not lit)
+		     (concat (org-trim contents t) "\n")
+		   contents)
+                 nil t)
                 nil t)
                nil t)
               linreset)
diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el
index adb3a60ea..79ef8793b 100644
--- a/testing/lisp/test-ox-latex.el
+++ b/testing/lisp/test-ox-latex.el
@@ -61,11 +61,11 @@ lorem ipsum dolor
      (search-forward
       "\\begin{verse}
 lorem ipsum dolor\\\\[0pt]
+lorem ipsum dolor
+
 lorem ipsum dolor\\\\[0pt]
-\\vspace*{1em}
-lorem ipsum dolor\\\\[0pt]
-lorem ipsum dolor\\\\[0pt]
-\\vspace*{1em}
+lorem ipsum dolor
+
 lorem ipsum dolor\\\\[0pt]
 lorem ipsum dolor\\\\[0pt]
 \\end{verse}"))))
-- 
2.41.0


^ permalink raw reply related	[relevance 23%]

* Re: [patch] ox-latex.el: fix blank lines behavior in verse block
  @ 2023-08-10 10:39 12%           ` Juan Manuel Macías
    0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2023-08-10 10:39 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: orgmode

Ihor Radchenko writes:

> Well. Technically, we already warn users that the blank lines are
> preserved in the verse blocks:
>
>     12.1 Paragraphs
>     ===============
>     
>     Paragraphs are separated by at least one empty line.  If you need to
>     enforce a line break within a paragraph, use ‘\\’ at the end of a line.
>     
>        To preserve the line breaks, indentation and blank lines in a region,
>     but otherwise use normal formatting, you can use this construct, which
>     can also be used to format poetry.
>     
>
>          #+BEGIN_VERSE
>           Great clouds overhead
>           Tiny black birds rise and fall
>           Snow covers Emacs
>     
>              ---AlexSchroeder
>          #+END_VERSE
>
> So, I now think that while extra cleanups might be OK for ox-latex, we
> may not want to ignore empty lines universally in all the verse blocks.

hmm, I don't know if phrased like that (as read in the documentation)
it's clear enough that the empty lines before and after the content are
also preserved. I would understand not, but it could also be a habit that
I inherited from LaTeX: I usually leave a blank line between the
#+begin/#+end directives and the content because it makes it easier for
me to read. I don't know if it is a widespread habit among other
users...

Anyway, I don't mind leaving things as they are in the other backends,
but in the case of LaTeX, with my patch modifications, it would be
necessary to remove the blank lines before and after the content.
Otherwise it would produce something like:

\begin{verse}
\\[0pt]
\\[0pt]
\\[0pt]
\\[0pt]
\\[0pt]
  lorem ipsum dolor
\end{verse}

which would return the error "There's no line here to end".

Also, the LaTeX 'verse' environment has its own syntax for vertical
spaces. It is not necessary to put an explicit \vspace just to separate
stanzas.

... In any case, the fact that the verse block can also be used to
literally export line breaks and horizontal/vertical spaces is
interesting. Something occurred to me that I don't know if it's a bit
foolhardy: how about a LaTeX attribute ':literal t'? If used, it would
not export to a verse environment (specialized in poetry) but to normal
text, without environment, but with line breaks and horizontal and
vertical spacing preserved... wdyt?


-- 
Juan Manuel Macías

https://juanmanuelmacias.com

https://lunotipia.juanmanuelmacias.com

https://gnutas.juanmanuelmacias.com


^ permalink raw reply	[relevance 12%]

* [patch] ox-latex.el: fix blank lines behavior in verse block
@ 2023-08-06 12:03 13% Juan Manuel Macías
    0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2023-08-06 12:03 UTC (permalink / raw)
  To: orgmode

[-- Attachment #1: Type: text/plain, Size: 3441 bytes --]

Rationale for this patch: the treatment of blank lines in
`org-latex-verse-block' is inconsistent with the syntax of the `verse'
environment, both the one that includes LaTeX and the one provided by
the `verse' package as a replacement for the former.

Currently, each blank line is exported to LaTeX as an explicit vertical
space: \vspace*{1em}. This can return unexpected results. For example,
this:

┌────
│ #+begin_verse
│
│ lorem
│ ipsum
│ dolor
| 
│ #+end_verse
└────

is exported to LaTeX as:

┌────
│ \begin{verse}
│ \vspace*{1em}
│ lorem\\[0pt]
│ ipsum\\[0pt]
│ dolor\\[0pt]
│ \vspace*{1em}
│ \end{verse}
└────

In the LaTeX `verse' environment, spaces before and after the content
are not taken into account.

As for the separation between stanzas, this is marked with at least one
blank line between the stanzas, as in normal paragraphs (not with an
explicit vertical space). Also it is not necessar y that the last verse
of each stanza ends with the linebreak mark `\\'.

So, after this patch:

• Any blank line before and/or after the content is removed;

• One or more blank lines between stanzas are exported as a single blank
  line, leaving the previous final verse without the linebreak mark
  `\\';

• When verse numbering is enabled via the `:lines' attribute (for the
  `verse' package), the last verses of each stanza are marked with
  `\\!', according to the verse package syntax (this was not necessary
  with the previous behavior).


This way, the `verse' block is exported to LaTeX with the correct
syntax. This also brings the advantage of being able to globally control
the spacing between stanzas via the verse package’s \stanzaskip command.

Example:

┌────
│ #+begin_verse
│ Lorem ipsum dolor
│ lorem ipsum dolor
│ lorem ipsum dolor
│
│ Lorem ipsum dolor
│ lorem ipsum dolor
│ lorem ipsum dolor
│
│ Lorem ipsum dolor
│ lorem ipsum dolor
│ lorem ipsum dolor
│ #+end_verse
└────

LaTeX:

┌────
│ \begin{verse}
│ Lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor
│
│ Lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor
│
│ Lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\[0pt]
│ \end{verse}
└────

And with verse numbers:

┌────
│ #+ATTR_LaTeX: :lines 5
│ #+begin_verse
│ Lorem ipsum dolor
│ lorem ipsum dolor
│ lorem ipsum dolor
│
│ Lorem ipsum dolor
│ lorem ipsum dolor
│ lorem ipsum dolor
│
│ Lorem ipsum dolor
│ lorem ipsum dolor
│ lorem ipsum dolor
│ #+end_verse
└────

LaTeX:

┌────
│ \begin{verse}
│ \poemlines{5}
│ Lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\!
│
│ Lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\!
│
│ Lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\[0pt]
│ lorem ipsum dolor\\[0pt]
│ \end{verse}
│ \poemlines{0}
└────

N.B.: the `\\[0pt]' mark of the last verse does not affect the final result.

Best regards,

Juan Manuel

--
Juan Manuel Macías

https://juanmanuelmacias.com

https://lunotipia.juanmanuelmacias.com

https://gnutas.juanmanuelmacias.com


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-lisp-ox-latex.el-fix-blank-lines-behavior-in-verse-b.patch --]
[-- Type: text/x-patch, Size: 1944 bytes --]

From 0c8a352567333d0d743b5235b68e9cd5d513f615 Mon Sep 17 00:00:00 2001
From: Juan Manuel Macias <maciaschain@posteo.net>
Date: Sun, 6 Aug 2023 12:42:36 +0200
Subject: [PATCH] lisp/ox-latex.el: fix blank lines behavior in verse block
 export.

* (org-latex-verse-block): now the treatment of blank lines is
consistent with the syntax of the LaTeX `verse' environment, and the
one provided by the `verse' package.
---
 lisp/ox-latex.el | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 31cad1dc4..26827537a 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -4128,20 +4128,28 @@ contextual information."
       verse-block
       ;; In a verse environment, add a line break to each newline
       ;; character and change each white space at beginning of a line
-      ;; into a space of 1 em.  Also change each blank line with
-      ;; a vertical space of 1 em.
+      ;; into a space of 1 em.  One or more blank lines between lines
+      ;; are exported as a single blank line.
       (format "%s\\begin{verse}%s\n%s\\end{verse}%s"
 	      vwidth
 	      attr
 	      (replace-regexp-in-string
 	       "^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m)))
 	       (replace-regexp-in-string
-                (concat "^[ \t]*" (regexp-quote org-latex-line-break-safe) "$")
-	        "\\vspace*{1em}"
+		(concat "\\("
+			(regexp-quote org-latex-line-break-safe)
+			"\n\\)"
+			"\\(^[ \t]*"
+			(regexp-quote org-latex-line-break-safe)
+			"\n"
+			"\\)+")
+		(if lin "\\\\!\n\n" "\n\n")
 	        (replace-regexp-in-string
 	         "\\([ \t]*\\\\\\\\\\)?[ \t]*\n"
                  (concat org-latex-line-break-safe "\n")
-	         contents nil t)
+	         ;; Remove any blank lines before and after CONTENTS.
+		 (concat (org-trim contents t) "\n")
+		 nil t)
                 nil t)
                nil t)
               linreset)
-- 
2.41.0


^ permalink raw reply related	[relevance 13%]

* Re: [Pre-PATCH] Overhaul of the LaTeX preview system
  @ 2023-06-03  9:00  9%     ` Rudolf Adamkovič
  0 siblings, 0 replies; 200+ results
From: Rudolf Adamkovič @ 2023-06-03  9:00 UTC (permalink / raw)
  To: Timothy; +Cc: emacs-orgmode

Timothy <orgmode@tec.tecosaur.net> writes:

> Thanks for testing the branch :)

Thank you for your reply.

> We’re thinking of adding `--exact-bbox' to the default `dvisvgm'
> flags, which it seems has a good chance of resolving this. It was
> originally swapped for `--bbox=preview' (when using `dvisvgm' to get
> dimension info), but now we do this via the LaTeX compilation stdout,
> and so we can go back to `--exact-bbox'.

This would be great.  Please!

> I tried this example on my computer, and it worked flawlessly (see
> <https://0x0.st/Hq7Z.png>). If you could give me a stacktrace, that
> might help.

OMG! OMG! OMG!  So, this new system not only fixes the baseline problem,
making LaTeX actually usable in HTML exports, but it also makes TikZ
work?!  No more fiddling with LaTeX Org Babel?  No more per-image
scaling headaches?  Now, that is INCREDIBLE!

Below, I re-create a MWE end-to-end.

******** CONFIGURATION ********

- OS:

macOS 13.3.1 (22E261)
ARM/M1 architecture
native compilation

- Org mode:

https://git.tecosaur.net/tec/org-mode.git
branch: origin/dev
commit: a92c62287

- Emacs:

official repository
branch: origin/master
commit: dc3b3548b7c
compilation flags:

make extraclean && ./autogen.sh && ./configure --with-json --with-xwidgets --with-native-compilation=aot && make -j 8 bootstrap && make install

- No '.emacs.d'.

- In '.emacs', the following:

;; Make Emacs native compilation work on Apple/macOS jails.
(when (eq window-system 'ns)
  (setenv "LIBRARY_PATH"
	    (string-join
	     '("/opt/homebrew/opt/gcc/lib/gcc/13"
	       "/opt/homebrew/opt/libgccjit/lib/gcc/13"
	       "/opt/homebrew/opt/gcc/lib/gcc/13/gcc/aarch64-apple-darwin22/13")
	     ":")))

;; Make Emacs find binaries on Apple/macOS jails.
(when (eq window-system 'ns)
  (defun shell-get-environment-variable+ (variable)
    "Return the value of VARIABLE from login shell."
    (shell-command-to-string
     (format "$SHELL --login -c 'echo -n $%s'" variable)))

  ;; Set the path to executables.
  (let* ((path "PATH")
         (path-value (shell-get-environment-variable+ path)))
    (setenv path path-value)
    (setq exec-path (split-string path-value path-separator)))

  ;; Set the locale.
  (let* ((variable "LC_ALL")
         (variable-value (shell-get-environment-variable+ variable)))
    (setenv variable variable-value)))

;; Load the new Org.
(add-to-list 'load-path "~/src/org-mode-tecosaur/lisp")

;; Make Org work without the arrow keys.
(setq-default org-use-extra-keys t)

******** TEST DOCUMENT ********

Saved in '~/test.org':

#+TITLE: Hello there
#+OPTIONS: tex:dvisvgm
#+LATEX_HEADER: \usepackage{tikz}

\begin{equation*}
1 + 1 = 2
\end{equation*}

\begin{tikzpicture}
  \filldraw (0, 0) circle[radius = 1cm];
\end{tikzpicture}

******** REPRODUCTION STEPS ********

1. Open the test document.
2. Type C-c C-x C-l inside of the 'equation' environment.
3. See the preview, to verify basic LaTeX previews work.
4. Type C-c C-x C-l inside of the 'tikzpicture' environment.

EXPECTED:

See the expected TikZ preview, a circle.

ACTUAL:

- No TikZ preview.
- "Wrong type argument: stringp, nil" in the echo area.

******** TRACE ********

The steps:

1. Type M-x toggle-debug-on-error RET.
2. Repeat the reproduction steps.
3. Expand all '...' in the trace.
4. Save the trace.

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  file-exists-p(nil)
  org-latex-preview--svg-make-fg-currentColor((:string "\\color[rgb]{0,0,0.00392157}\\setcounter{equation}{0}%\n\\begin{tikzpicture}\n  \\filldraw (0, 0) circle[radius = 1cm];\n\\end{tikzpicture}\n" :overlay #<overlay from 125 to 203 in test.org> :key "6f292c841630b664deb0178c18bdfc5ceb532272" :depth 0.04918392937239927 :height 5.714304984431469 :width 36.21927976341847 :errors nil :path nil :error "Image file not produced."))
  org-latex-preview--dvisvgm-filter(#<process org-async-dvisvgm-4> "processing page 1\n  WARNING: 50 PostScript specials ignored. The resulting SVG might look wrong.\n  page is empty\n  graphic size: 0pt x 0pt (0mm x 0mm)\n  output written to /var/folders/ky/8r5j3qz55hb94lpg1jr9vl1c0000gn/T/org-tex-4tn7FE-000000001.svg\n1 of 1 page converted in 0.153852 seconds\n" (:latex-processor "pdflatex" :latex-header "% Intended LaTeX compiler: pdflatex\n\\documentclass{article}\n\\usepackage[utf8]{inputenc}\n\\usepackage[T1]{fontenc}\n% Package hyperref omitted\n\\usepackage{xcolor}\n\n\\usepackage{tikz}\n\n\n% Generated preamble omitted for snippets.\n\n\n\\makeatletter\n\\renewcommand{\\theequation}{\\(\\diamond\\)\\ifnum\\value{equation}>1%\n\\,+\\,\\@arabic{\\numexpr\\value{equation}-1\\relax}\\fi}\n\\makeatother" :programs ("latex" "dvisvgm") :description "dvi > svg" :message "you need to install the programs: latex and dvisvgm." :image-input-type "dvi" :image-output-type "svg" :latex-compiler ("%l -interaction nonstopmode -output-directory %o %f") :latex-precompiler ("%l -output-directory %o -ini -jobname=%b \"&%L\" mylatexformat.ltx %f") :image-converter ("dvisvgm --page=1- --optimize --clipjoin --relative --no-fonts --bbox=preview -o %B-%%9p.svg %f") :processor dvisvgm :fragments ((:string "\\color[rgb]{0,0,0.00392157}\\setcounter{equation}{0}%\n\\begin{tikzpicture}\n  \\filldraw (0, 0) circle[radius = 1cm];\n\\end{tikzpicture}\n" :overlay #<overlay from 125 to 203 in test.org> :key "6f292c841630b664deb0178c18bdfc5ceb532272" :depth 0.04918392937239927 :height 5.714304984431469 :width 36.21927976341847 :errors nil :path nil :error "Image file not produced.")) :org-buffer #<buffer test.org> :texfile "/Users/salutis/org-tex-4tn7FE.tex" :place-preview-p t :fontsize 10 :tightpage (-32891 -32891 32891 32891)))
  org-async--filter(#<process org-async-dvisvgm-4> "processing page 1\n  WARNING: 50 PostScript specials ignored. The resulting SVG might look wrong.\n  page is empty\n  graphic size: 0pt x 0pt (0mm x 0mm)\n  output written to /var/folders/ky/8r5j3qz55hb94lpg1jr9vl1c0000gn/T/org-tex-4tn7FE-000000001.svg\n1 of 1 page converted in 0.153852 seconds\n")

Rudy
-- 
"Mathematics takes us still further from what is human into the region
of absolute necessity, to which not only the actual world, but every
possible world, must conform."
-- Bertrand Russell, 1902

Rudolf Adamkovič <salutis@me.com> [he/him]
Studenohorská 25
84103 Bratislava
Slovakia


^ permalink raw reply	[relevance 9%]

* Re: orgtable to latex export \hline[0pt] why?
  2023-04-22 12:13 20%   ` Uwe Brauer
@ 2023-04-22 12:32 10%     ` Ihor Radchenko
  0 siblings, 0 replies; 200+ results
From: Ihor Radchenko @ 2023-04-22 12:32 UTC (permalink / raw)
  To: Uwe Brauer; +Cc: emacs-orgmode

Uwe Brauer <oub@mat.ucm.es> writes:

> I could modify that function, but again what is the purpose of the [0pt]

See https://list.orgmode.org/orgmode/CAO12V+wB18nAN0FuDPAeN94GHdt_2nbdJtc4u7n4W3HAZbaZsA@mail.gmail.com/
Also, note `org-latex-line-break-safe'.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 10%]

* Re: orgtable to latex export \hline[0pt] why?
  2023-04-22 11:32 18% ` Ihor Radchenko
@ 2023-04-22 12:13 20%   ` Uwe Brauer
  2023-04-22 12:32 10%     ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Uwe Brauer @ 2023-04-22 12:13 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Uwe Brauer, emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1311 bytes --]

>>> "IR" == Ihor Radchenko <yantar92@posteo.net> writes:

> Uwe Brauer <oub@mat.ucm.es> writes:
>> After pulling the latest org mode, the following table
>> 
>> Is exported to latex as
>> ...
>> \begin{center}
>> \begin{tabular}{rrrrrrrrr}
>> Ej1A & Ej1B & EjC & E2A1 & E2B & E2C & E2D & E2E & Total\\ \hline[0pt]
>> \hline

> I am seeing

> \begin{center}
> \begin{tabular}{rrrrrrrrr}
> Ej1A & Ej1B & EjC & E2A1 & E2B & E2C & E2D & E2E & Total\\[0pt]
> \hline

Well what is the purpose of the [0pt], that is new. Concerning the \hline

(defun my-latex-insert-hline-always (row backend info)
  "Add a hline to every row when exporting to  LaTeX."
  (when (org-export-derived-backend-p backend 'latex)
    (replace-regexp-in-string "\\\\\\\\" "\\\\\\\\ \\\\hline" row)))

(add-to-list 'org-export-filter-table-row-functions 'my-latex-insert-hline-always)


I could modify that function, but again what is the purpose of the [0pt]


-- 
Warning: Content may be disturbing to some audiences
I strongly condemn Putin's war of aggression against the Ukraine.
I support to deliver weapons to Ukraine's military. 
I support the ban of Russia from SWIFT.
I support the EU membership of the Ukraine. 
https://addons.thunderbird.net/en-US/thunderbird/addon/gmail-conversation-view/

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5673 bytes --]

^ permalink raw reply	[relevance 20%]

* Re: orgtable to latex export \hline[0pt] why?
  2023-04-21 14:00 22% orgtable to latex export \hline[0pt] why? Uwe Brauer
@ 2023-04-22 11:32 18% ` Ihor Radchenko
  2023-04-22 12:13 20%   ` Uwe Brauer
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2023-04-22 11:32 UTC (permalink / raw)
  To: Uwe Brauer; +Cc: emacs-orgmode

Uwe Brauer <oub@mat.ucm.es> writes:

> After pulling the latest org mode, the following table
>
> Is exported to latex as
> ...
> \begin{center}
> \begin{tabular}{rrrrrrrrr}
> Ej1A & Ej1B & EjC & E2A1 & E2B & E2C & E2D & E2E & Total\\ \hline[0pt]
> \hline

I am seeing

\begin{center}
\begin{tabular}{rrrrrrrrr}
Ej1A & Ej1B & EjC & E2A1 & E2B & E2C & E2D & E2E & Total\\[0pt]
\hline

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 18%]

* orgtable to latex export \hline[0pt] why?
@ 2023-04-21 14:00 22% Uwe Brauer
  2023-04-22 11:32 18% ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Uwe Brauer @ 2023-04-21 14:00 UTC (permalink / raw)
  To: emacs-orgmode


Hi

After pulling the latest org mode, the following table



  | Ej1A | Ej1B | EjC | E2A1 | E2B | E2C | E2D | E2E | Total |
  |------+------+-----+------+-----+-----+-----+-----+-------|
  |   10 |   15 |  10 |   10 |  20 |  10 |  15 |  10 |   100 |
  |   10 |    0 |  10 |   10 |  20 |  10 |  15 |  10 |    85 |
  |      |      |     |      |     |     |     |     |       |
  |   10 |    0 |  10 |   10 |  20 |  10 |  15 |  10 |    85 |

Is exported to latex as

\begin{center}
\begin{tabular}{rrrrrrrrr}
Ej1A & Ej1B & EjC & E2A1 & E2B & E2C & E2D & E2E & Total\\ \hline[0pt]
\hline
10 & 15 & 10 & 10 & 20 & 10 & 15 & 10 & 100\\ \hline[0pt]
10 & 0 & 10 & 10 & 20 & 10 & 15 & 10 & 85\\ \hline[0pt]
 &  &  &  &  &  &  &  & \\ \hline[0pt]
10 & 0 & 10 & 10 & 20 & 10 & 15 & 10 & 85\\ \hline[0pt]
\end{tabular}
\end{center}

Now, \hline[0pt] gives an error when I compile it with texlive 2019.

    1. Why was the exporter changed.

    2. How can I turn this \hline[0pt] off?

Thanks

Uwe Brauer 

-- 
Warning: Content may be disturbing to some audiences
I strongly condemn Putin's war of aggression against the Ukraine.
I support to deliver weapons to Ukraine's military. 
I support the ban of Russia from SWIFT.
I support the EU membership of the Ukraine. 
https://addons.thunderbird.net/en-US/thunderbird/addon/gmail-conversation-view/



^ permalink raw reply	[relevance 22%]

* Re: [TIP] Exporting Maxima results to LaTeX
  @ 2023-02-11 11:39 10%     ` Max Nikulin
  0 siblings, 0 replies; 200+ results
From: Max Nikulin @ 2023-02-11 11:39 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: Leo Butler

On 09/02/2023 03:40, Leo Butler wrote:
> On Wed, Feb 08 2023, Max Nikulin wrote:
>> I am curious if it is possible to avoid duplication by e.g. using noweb.
> 
> ... I am not aware of how to
> remove that duplication--all the examples I have found in the worg
> source do what I have done above.

I have tried

---- >8 ----
#+begin_src elisp :exports results :results silent
   (require 'ob-org)
#+end_src

#+begin_src org :exports both :results drawer replace
   ,#+begin_src elisp :exports results
     '((1 2 3) (4 5 6))
   ,#+end_src
#+end_src
---- 8< ----

It is exported to LaTeX as

---- >8 ----
\begin{verbatim}
#+begin_src elisp :exports results
   '((1 2 3) (4 5 6))
#+end_src
\end{verbatim}

\begin{center}
\begin{tabular}{rrr}
1 & 2 & 3\\[0pt]
4 & 5 & 6\\[0pt]
\end{tabular}
\end{center}
---- 8< ----

For debugging of the inner src block it is necessary to swap escaping 
with the outer #+begin_src. I have not figured out how to add some text 
in between of the exported source code example and its result.


^ permalink raw reply	[relevance 10%]

* Re: [PATCH] oc-csl: Improve LaTeX bibliography formatting
  @ 2022-12-27 22:32  4%               ` András Simonyi
  0 siblings, 0 replies; 200+ results
From: András Simonyi @ 2022-12-27 22:32 UTC (permalink / raw)
  To: Timothy; +Cc: Ihor Radchenko, emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1032 bytes --]

Dear All,
I have attached a new version of the patch with added ascii "illustrations".
best wishes,
András

On Tue, 13 Dec 2022 at 20:03, András Simonyi <andras.simonyi@gmail.com> wrote:
>
> Dear All,
>
> On Tue, 13 Dec 2022 at 17:07, Timothy <orgmode@tec.tecosaur.net> wrote:
>
> > Perhaps an ASCII approximation in an example block could work? Even if it’s
> > exaggerated to give the idea.
>
> yes, I'm also thinking of first trying to produce something in ASCII
> as the docstring will probably need it anyway,
> and we can think about the image version afterwards -- it might turn
> out that the text version is already sufficient for the news (and
> maybe later on for the manual).
>
> best wishes,
> András
>
> > All the best,
> > Timothy
> >
> > --
> > Timothy (‘tecosaur’/‘TEC’), Org mode contributor.
> > Learn more about Org mode at <https://orgmode.org/>.
> > Support Org development at <https://liberapay.com/org-mode>,
> > or support my work at <https://liberapay.com/tec>.

[-- Attachment #2: 0001-oc-csl-Improve-LaTeX-bibliography-formatting.patch --]
[-- Type: text/x-patch, Size: 10988 bytes --]

From 2bdbb02901b9831f3bb6b3d29ff8050eadd69e46 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A1s=20Simonyi?= <andras.simonyi@gmail.com>
Date: Tue, 27 Dec 2022 23:15:34 +0100
Subject: [PATCH] oc-csl: Improve LaTeX bibliography formatting

* lisp/oc-csl.el (org-cite-csl--output-format): Use the dedicated
'org-latex' citeproc formatter to export references in LaTeX.
(org-cite-csl-latex-preamble, org-cite-csl--generate-latex-preamble,
org-cite-csl-finalizer): Insert a preamble fragment compatible with
the 'org-latex' citeproc formatter.
(org-cite-csl-latex-label-separator,
org-cite-csl-latex-label-width-per-char): Introduce additional
variables to control bibliography formatting.

* etc/ORG-NEWS: Describe the introduced new options.
---
 etc/ORG-NEWS   |  27 +++++++++
 lisp/oc-csl.el | 145 +++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 155 insertions(+), 17 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index d4e9b4368..1185a51b2 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -13,6 +13,33 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
 
 * Version 9.7 (not released yet)
 ** New options
+*** New custom settings for the "csl" citation export processor's LaTeX output
+
+The settings ~org-cite-csl-latex-label-separator~ and
+~org-cite-csl-latex-label-width-per-char~ allow the user to control
+the indentation of entries for labeled bibliography styles when the
+"csl" citation processor is used for LaTeX export.  The indentation
+length is computed as the sum of ~org-cite-csl-latex-label-separator~
+and the maximal label width, for example:
+
+#+begin_example
+    indentation length
+<------------------------->
+max. label width  separator
+<---------------><-------->
+[Doe22]                    John Doe. A title...
+[DoeSmithJones19]          John Doe, Jane Smith and...
+[SmithDoe02]               Jane Smith and John Doe...
+#+end_example
+
+The maximal label width, in turn, is calculated as the product of
+~org-cite-csl-latex-label-width-per-char~ and the maximal label length
+measured in characters.
+
+The setting ~org-cite-csl-latex-preamble~ makes it possible to
+customize the entire LaTeX fragment that the "csl" citation processor injects
+into the preamble.
+
 *** New ~org-latex-listings-src-omit-language~ customization for LaTeX export
 
 The ~org-latex-listings-src-omit-language~ customization variable
diff --git a/lisp/oc-csl.el b/lisp/oc-csl.el
index 1ccb74e92..11194b9b4 100644
--- a/lisp/oc-csl.el
+++ b/lisp/oc-csl.el
@@ -214,6 +214,111 @@ Used only when `second-field-align' is activated by the used CSL style."
   :type 'string
   :safe #'stringp)
 
+(defcustom org-cite-csl-latex-label-separator "0.6em"
+  "Distance between citation label and bibliography item for LaTeX
+output in valid LaTeX units.  Used only when `second-field-align'
+is activated by the used CSL style.
+
+The indentation length in these cases is computed as the sum of
+`org-cite-csl-latex-label-separator' and the maximal label width,
+for example,
+
+    indentation length
+<------------------------->
+max. label width  separator
+<---------------><-------->
+[Doe22]                    John Doe. A title...
+[DoeSmithJones19]          John Doe, Jane Smith and...
+[SmithDoe02]               Jane Smith and John Doe...
+
+The maximal label width, in turn, is calculated as the product of
+`org-cite-csl-latex-label-width-per-char' and the maximal label
+length measured in characters."
+  :group 'org-cite
+  :package-version '(Org . "9.7")
+  :type 'string
+  :safe #'stringp)
+
+(defcustom org-cite-csl-latex-label-width-per-char "0.45em"
+  "Character width in LaTeX units for calculating entry label widths.
+Used only when `second-field-align' is activated by the used CSL
+style.
+
+See the documentation of `org-cite-csl-latex-label-separator' for
+details."
+  :group 'org-cite
+  :package-version '(Org . "9.7")
+  :type 'string
+  :safe #'stringp)
+
+;; The following was inspired by and in many details follows how
+;; Pandoc's (<https://github.com/jgm/pandoc>) default LaTeX template
+;; handles CSL output.  Many thanks to the author, John MacFarlane!
+(defcustom org-cite-csl-latex-preamble
+  "\\usepackage{calc}
+\\newlength{\\cslhangindent}
+\\setlength{\\cslhangindent}{[CSL-HANGINDENT]}
+\\newlength{\\csllabelsep}
+\\setlength{\\csllabelsep}{[CSL-LABELSEP]}
+\\newlength{\\csllabelwidth}
+\\setlength{\\csllabelwidth}{[CSL-LABELWIDTH-PER-CHAR] * [CSL-MAXLABEL-CHARS]}
+\\newenvironment{cslbibliography}[2] % 1st arg. is hanging-indent, 2nd entry spacing.
+ {% By default, paragraphs are not indented.
+  \\setlength{\\parindent}{0pt}
+  % Hanging indent is turned on when first argument is 1.
+  \\ifodd #1
+  \\let\\oldpar\\par
+  \\def\\par{\\hangindent=\\cslhangindent\\oldpar}
+  \\fi
+  % Set entry spacing based on the second argument.
+  \\setlength{\\parskip}{\\parskip +  #2\\baselineskip}
+ }%
+ {}
+\\newcommand{\\cslblock}[1]{#1\\hfill\\break}
+\\newcommand{\\cslleftmargin}[1]{\\parbox[t]{\\csllabelsep + \\csllabelwidth}{#1}}
+\\newcommand{\\cslrightinline}[1]
+  {\\parbox[t]{\\linewidth - \\csllabelsep - \\csllabelwidth}{#1}\\break}
+\\newcommand{\\cslindent}[1]{\\hspace{\\cslhangindent}#1}
+\\newcommand{\\cslbibitem}[2]
+  {\\leavevmode\\vadjust pre{\\hypertarget{citeproc_bib_item_#1}{}}#2}
+\\makeatletter
+\\newcommand{\\cslcitation}[2]
+ {\\protect\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}
+\\makeatother"
+  "LaTeX preamble content inserted by the `csl' citation processor.
+
+This preamble can be anything as long as it provides definitions
+for the environment and commands that Citeproc's `org-latex'
+formatter uses for formatting citations and bibliographies.  In
+particular, it has to define
+- the commands \\cslblock{<text>}, \\cslleftmargin{<text>},
+  \\cslrightinline{<text>} and \\cslindent{<text>} for formatting
+  text that have, respectively, the CSL display attributes
+  `block', `left-margin', `right-inline' and `indent';
+- the commands \\cslcitation{<item_no>}{<item_text>} and
+  \\cslbibitem{<item_no>}{<item_text>}, which are used to
+  format individual citations and bibliography items, including
+  hyperlinking citations to the corresponding bibliography entry
+  using their numerical id, which is passed as the first,
+  <item_no> argument;
+- and the environment \\cslbibliography{<hanging-indent>}{<entry-spacing>},
+  in which bibliographies are wrapped; the value of the
+  <hanging-indent> argument is 1 if hanging indent should be
+  applied and 0 if not, while the <entry-spacing> argument is an
+  integer specifying the number of extra line-heights
+  required between bibliography entries in addition to normal
+  line spacing.
+
+When present, the placeholders [CSL-HANGINDENT], [CSL-LABELSEP],
+[CSL-LABELWIDTH-PER-CHAR] and [CSL-MAXLABEL-CHARS] are replaced,
+respectively, by the contents of the customizable variables
+`org-cite-csl-latex-hanging-indent', `org-cite-csl-latex-label-separator',
+`org-cite-csl-latex-label-width-per-char', and the maximal label length
+in the bibliography measured in characters."
+  :group 'org-cite
+  :type 'string
+  :package-version '(Org . "9.7"))
+
 \f
 ;;; Internal variables
 (defconst org-cite-csl--etc-dir
@@ -413,7 +518,7 @@ corresponding to one of the output formats supported by Citeproc: `html',
   (let ((backend (plist-get info :back-end)))
     (cond
      ((org-export-derived-backend-p backend 'html) 'html)
-     ((org-export-derived-backend-p backend 'latex) 'latex)
+     ((org-export-derived-backend-p backend 'latex) 'org-latex)
      (t 'org))))
 
 (defun org-cite-csl--style-file (info)
@@ -670,6 +775,21 @@ value is the bibliography as rendered by Citeproc."
             (plist-put info :cite-citeproc-rendered-bibliographies result)
             result)))))
 
+(defun org-cite-csl--generate-latex-preamble (info)
+  "Generate the CSL-related part of the LaTeX preamble.
+INFO is the export state, as a property list."
+  (let* ((parameters (cadr (org-cite-csl--rendered-bibliographies info)))
+         (max-offset (cdr (assq 'max-offset parameters)))
+         (result org-cite-csl-latex-preamble))
+    (map-do (lambda (placeholder replacement)
+              (when (string-match placeholder result)
+                (setq result (replace-match replacement t t result))))
+            `("\\[CSL-HANGINDENT\\]" ,org-cite-csl-latex-hanging-indent
+              "\\[CSL-LABELSEP\\]" ,org-cite-csl-latex-label-separator
+              "\\[CSL-LABELWIDTH-PER-CHAR\\]" ,org-cite-csl-latex-label-width-per-char
+              "\\[CSL-MAXLABEL-CHARS\\]" ,(number-to-string max-offset)))
+    result))
+
 \f
 ;;; Export capability
 (defun org-cite-csl-render-citation (citation _style _backend info)
@@ -688,8 +808,8 @@ INFO is the export state, as a property list."
 INFO is the export state, as a property list."
   (org-cite-csl--barf-without-citeproc)
   (pcase-let*  ((format (org-cite-csl--output-format info))
-		(`(,outputs ,parameters) (org-cite-csl--rendered-bibliographies info))
-		(output (cdr (assoc props outputs))))
+                (`(,outputs ,parameters) (org-cite-csl--rendered-bibliographies info))
+                (output (cdr (assoc props outputs))))
     (pcase format
       ('html
        (concat
@@ -714,12 +834,7 @@ INFO is the export state, as a property list."
               org-cite-csl-html-hanging-indent
               org-cite-csl-html-hanging-indent))
         output))
-      ('latex
-       (if (cdr (assq 'hanging-indent parameters))
-           (format "\\begin{hangparas}{%s}{1}\n%s\n\\end{hangparas}"
-                   org-cite-csl-latex-hanging-indent
-                   output)
-         output))
+      ('org-latex output)
       (_
        ;; Parse Org output to re-export it during the regular export
        ;; process.
@@ -730,18 +845,14 @@ INFO is the export state, as a property list."
 OUTPUT is the export document, as a string.  INFO is the export state, as a
 property list."
   (org-cite-csl--barf-without-citeproc)
-  (if (not (eq 'latex (org-cite-csl--output-format info)))
+  (if (not (eq 'org-latex (org-cite-csl--output-format info)))
       output
     (with-temp-buffer
       (save-excursion (insert output))
       (when (search-forward "\\begin{document}" nil t)
-        (goto-char (match-beginning 0))
-        ;; Ensure that \citeprocitem is defined for citeproc-el.
-        (insert "\\makeatletter\n\\newcommand{\\citeprocitem}[2]{\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}\n\\makeatother\n\n")
-        ;; Ensure there is a \usepackage{hanging} somewhere or add one.
-        (let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{hanging}")))
-          (unless (re-search-backward re nil t)
-            (insert "\\usepackage[notquote]{hanging}\n"))))
+	(goto-char (match-beginning 0))
+	;; Insert the CSL-specific parts of the LaTeX preamble.
+	(insert (org-cite-csl--generate-latex-preamble info)))
       (buffer-string))))
 
 \f
-- 
2.25.1


^ permalink raw reply related	[relevance 4%]

* Re: [PATCH] oc-csl: Improve LaTeX bibliography formatting
  @ 2022-12-11 19:00  4%       ` András Simonyi
    0 siblings, 1 reply; 200+ results
From: András Simonyi @ 2022-12-11 19:00 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode list

[-- Attachment #1: Type: text/plain, Size: 3201 bytes --]

Dear All,

first of all, apologies for the delay, unfortunately, I haven't been
able to work on my WIP patches for a while. Now I've attached a new
version of the patch, which hopefully addresses all issues discussed
earlier.

best wishes,
András

On Tue, 8 Nov 2022 at 06:26, Ihor Radchenko <yantar92@posteo.net> wrote:
>
> András Simonyi <andras.simonyi@gmail.com> writes:
>
> >> Also, it would be nice to describe CSL usage and tweaks in the manual.
> >
> > Time permitting I may try to add something, but wouldn't it be a
> > problem if the CSL export processor was discussed in much more detail
> > than the others?
> > I was also thinking about providing a list of available citation
> > substyles but I do not want to make the manual very unbalanced.
>
> Maybe not in the release, but otherwise we need to finish the citation
> section of the manual one way or another. May as well start from CSL
> part.
>
> >> I have two comments here:
> >> 1. Where are all these new commands coming from? They are not used
> >>    directly in the code. Are you tweaking citeproc.el output this way? May
> >>    it be better to use customizations provided by citeproc.el itself?
> >
> > Yes, the citeproc org-latex formatter, which I added specifically for
> > Org, uses these commands in the LaTeX code produced for the
> > bibliography. As citeproc doesn't have customizable variables by
> > design (if I recall correctly, the only exception is 2 hooks), and
> > oc-csl already had some variables concerned with very similar
> > formatting settings (org-cite-csl-latex-hanging-indent,
> > org-cite-csl-html-hanging-indent,
> > org-cite-csl-html-label-width-per-char) I think it is more consistent
> > to have the new ones also in Org.
>
> Thanks for the clarification. I'd prefer to see a similar explanation
> and the details about what the LaTeX variables/commands do in the
> docstring.
>
> >> 2. You are declaring this variable as defcustom, but it is not clear
> >>    what is going to happen if the user changes it. It is not how to
> >>    change this template in meaningful ways either.
> >
> > Right, I can try to detail a bit in the docstring what type of
> > commands and environments have to be provided by the preamble (are
> > expected by citeproc). I tried to follow Timothy's handling of the
> > ox-latex engraved preamble, but a simpler alternative would be to
> > treat it simply as a constant template, at least for the time being --
> > WDYT?
>
> Note that `org-latex-engraved-preamble' explains which packages need to
> be loaded and which commands need to be defined in the preamble. This at
> least make it more clear what the users may change and not break the
> export.
>
> I see not problem keeping this a defcustom, but we definitely need to
> explain the default value and what is required to be in there. At least,
> to make the code readable for future contributors.
>
> --
> Ihor Radchenko // yantar92,
> Org mode contributor,
> Learn more about Org mode at <https://orgmode.org/>.
> Support Org development at <https://liberapay.com/org-mode>,
> or support my work at <https://liberapay.com/yantar92>

[-- Attachment #2: 0001-oc-csl-Improve-LaTeX-bibliography-formatting.patch --]
[-- Type: text/x-patch, Size: 9670 bytes --]

From 7f02881ff1ef9c3dd3eca0cd63a91936dcb90a45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A1s=20Simonyi?= <andras.simonyi@gmail.com>
Date: Sun, 11 Dec 2022 18:03:39 +0100
Subject: [PATCH] oc-csl: Improve LaTeX bibliography formatting

* lisp/oc-csl.el (org-cite-csl--output-format): Use the dedicated
'org-latex' citeproc formatter to export references in LaTeX.
(org-cite-csl-latex-preamble, org-cite-csl--generate-latex-preamble,
org-cite-csl-finalizer): Insert a preamble fragment compatible with
the 'org-latex' citeproc formatter.
(org-cite-csl-latex-label-separator,
org-cite-csl-latex-label-width-per-char): Introduce additional
variables to control bibliography formatting.

* etc/ORG-NEWS: Describe the introduced new options.
---
 etc/ORG-NEWS   |  11 +++++
 lisp/oc-csl.el | 126 ++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 5d5e726e0..6441cdc1f 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -12,6 +12,17 @@ See the end of the file for license conditions.
 Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
 
 * Version 9.7 (not released yet)
+
+** New options
+*** New custom settings for the "csl" citation export processor's LaTeX output
+
+The settings ~org-cite-csl-latex-label-separator~ and
+~org-cite-csl-latex-label-width-per-char~ allow the user to control
+the horizontal positioning of entry labels for labeled bibliography
+styles, and the setting ~org-cite-csl-latex-preamble~ makes it
+possible to customize the entire fragment that is injected into the
+preamble when the "csl" citation processor is used for LaTeX export.
+
 * Version 9.6
 
 ** Important announcements and breaking changes
diff --git a/lisp/oc-csl.el b/lisp/oc-csl.el
index 1ccb74e92..e3f57918c 100644
--- a/lisp/oc-csl.el
+++ b/lisp/oc-csl.el
@@ -214,6 +214,92 @@ Used only when `second-field-align' is activated by the used CSL style."
   :type 'string
   :safe #'stringp)
 
+(defcustom org-cite-csl-latex-label-separator "0.6em"
+  "Distance between citation label and bibliography item for LaTeX
+output in valid LaTeX units.  Used only when `second-field-align'
+is activated by the used CSL style."
+  :group 'org-cite
+  :package-version '(Org . "9.7")
+  :type 'string
+  :safe #'stringp)
+
+(defcustom org-cite-csl-latex-label-width-per-char "0.45em"
+  "Character width in LaTeX units for calculating entry label widths.
+Used only when `second-field-align' is activated by the used CSL
+style."
+  :group 'org-cite
+  :package-version '(Org . "9.7")
+  :type 'string
+  :safe #'stringp)
+
+;; The following was inspired by and in many details follows how
+;; Pandoc's (<https://github.com/jgm/pandoc>) default LaTeX template
+;; handles CSL output.  Many thanks to the author, John MacFarlane!
+(defcustom org-cite-csl-latex-preamble
+  "\\usepackage{calc}
+\\newlength{\\cslhangindent}
+\\setlength{\\cslhangindent}{[CSL-HANGINDENT]}
+\\newlength{\\csllabelsep}
+\\setlength{\\csllabelsep}{[CSL-LABELSEP]}
+\\newlength{\\csllabelwidth}
+\\setlength{\\csllabelwidth}{[CSL-LABELWIDTH-PER-CHAR] * [CSL-MAXLABEL-CHARS]}
+\\newenvironment{cslbibliography}[2] % 1st arg. is hanging-indent, 2nd entry spacing.
+ {% By default, paragraphs are not indented.
+  \\setlength{\\parindent}{0pt}
+  % Hanging indent is turned on when first argument is 1.
+  \\ifodd #1
+  \\let\\oldpar\\par
+  \\def\\par{\\hangindent=\\cslhangindent\\oldpar}
+  \\fi
+  % Set entry spacing based on the second argument.
+  \\setlength{\\parskip}{\\parskip +  #2\\baselineskip}
+ }%
+ {}
+\\newcommand{\\cslblock}[1]{#1\\hfill\\break}
+\\newcommand{\\cslleftmargin}[1]{\\parbox[t]{\\csllabelsep + \\csllabelwidth}{#1}}
+\\newcommand{\\cslrightinline}[1]
+  {\\parbox[t]{\\linewidth - \\csllabelsep - \\csllabelwidth}{#1}\\break}
+\\newcommand{\\cslindent}[1]{\\hspace{\\cslhangindent}#1}
+\\newcommand{\\cslbibitem}[2]
+  {\\leavevmode\\vadjust pre{\\hypertarget{citeproc_bib_item_#1}{}}#2}
+\\makeatletter
+\\newcommand{\\cslcitation}[2]
+ {\\protect\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}
+\\makeatother"
+  "LaTeX preamble content inserted by the `csl' citation processor.
+
+This preamble can be anything as long as it provides definitions
+for the environment and commands that Citeproc's `org-latex'
+formatter uses for formatting citations and bibliographies.  In
+particular, it has to define
+- the commands \\cslblock{<text>}, \\cslleftmargin{<text>},
+  \\cslrightinline{<text>} and \\cslindent{<text>} for formatting
+  text that have, respectively, the CSL display attributes
+  `block', `left-margin', `right-inline' and `indent';
+- the commands \\cslcitation{<item_no>}{<item_text>} and
+  \\cslbibitem{<item_no>}{<item_text>}, which are used to
+  format individual citations and bibliography items, including
+  hyperlinking citations to the corresponding bibliography entry
+  using their numerical id, which is passed as the first,
+  <item_no> argument;
+- and the environment \\cslbibliography{<hanging-indent>}{<entry-spacing>},
+  in which bibliographies are wrapped; the value of the
+  <hanging-indent> argument is 1 if hanging indent should be
+  applied and 0 if not, while the <entry-spacing> argument is an
+  integer specifying the number of extra line-heights
+  required between bibliography entries in addition to normal
+  line spacing.
+
+When present, the placeholders [CSL-HANGINDENT], [CSL-LABELSEP],
+[CSL-LABELWIDTH-PER-CHAR] and [CSL-MAXLABEL-CHARS] are replaced,
+respectively, by the contents of the customizable variables
+`org-cite-csl-latex-hanging-indent', `org-cite-csl-latex-label-separator',
+`org-cite-csl-latex-label-width-per-char', and the maximal label length
+in the bibliography measured in characters."
+  :group 'org-cite
+  :type 'string
+  :package-version '(Org . "9.7"))
+
 \f
 ;;; Internal variables
 (defconst org-cite-csl--etc-dir
@@ -413,7 +499,7 @@ corresponding to one of the output formats supported by Citeproc: `html',
   (let ((backend (plist-get info :back-end)))
     (cond
      ((org-export-derived-backend-p backend 'html) 'html)
-     ((org-export-derived-backend-p backend 'latex) 'latex)
+     ((org-export-derived-backend-p backend 'latex) 'org-latex)
      (t 'org))))
 
 (defun org-cite-csl--style-file (info)
@@ -670,6 +756,21 @@ value is the bibliography as rendered by Citeproc."
             (plist-put info :cite-citeproc-rendered-bibliographies result)
             result)))))
 
+(defun org-cite-csl--generate-latex-preamble (info)
+  "Generate the CSL-related part of the LaTeX preamble.
+INFO is the export state, as a property list."
+  (let* ((parameters (cadr (org-cite-csl--rendered-bibliographies info)))
+         (max-offset (cdr (assq 'max-offset parameters)))
+         (result org-cite-csl-latex-preamble))
+    (map-do (lambda (placeholder replacement)
+              (when (string-match placeholder result)
+                (setq result (replace-match replacement t t result))))
+            `("\\[CSL-HANGINDENT\\]" ,org-cite-csl-latex-hanging-indent
+              "\\[CSL-LABELSEP\\]" ,org-cite-csl-latex-label-separator
+              "\\[CSL-LABELWIDTH-PER-CHAR\\]" ,org-cite-csl-latex-label-width-per-char
+              "\\[CSL-MAXLABEL-CHARS\\]" ,(number-to-string max-offset)))
+    result))
+
 \f
 ;;; Export capability
 (defun org-cite-csl-render-citation (citation _style _backend info)
@@ -688,8 +789,8 @@ INFO is the export state, as a property list."
 INFO is the export state, as a property list."
   (org-cite-csl--barf-without-citeproc)
   (pcase-let*  ((format (org-cite-csl--output-format info))
-		(`(,outputs ,parameters) (org-cite-csl--rendered-bibliographies info))
-		(output (cdr (assoc props outputs))))
+                (`(,outputs ,parameters) (org-cite-csl--rendered-bibliographies info))
+                (output (cdr (assoc props outputs))))
     (pcase format
       ('html
        (concat
@@ -714,12 +815,7 @@ INFO is the export state, as a property list."
               org-cite-csl-html-hanging-indent
               org-cite-csl-html-hanging-indent))
         output))
-      ('latex
-       (if (cdr (assq 'hanging-indent parameters))
-           (format "\\begin{hangparas}{%s}{1}\n%s\n\\end{hangparas}"
-                   org-cite-csl-latex-hanging-indent
-                   output)
-         output))
+      ('org-latex output)
       (_
        ;; Parse Org output to re-export it during the regular export
        ;; process.
@@ -730,18 +826,14 @@ INFO is the export state, as a property list."
 OUTPUT is the export document, as a string.  INFO is the export state, as a
 property list."
   (org-cite-csl--barf-without-citeproc)
-  (if (not (eq 'latex (org-cite-csl--output-format info)))
+  (if (not (eq 'org-latex (org-cite-csl--output-format info)))
       output
     (with-temp-buffer
       (save-excursion (insert output))
       (when (search-forward "\\begin{document}" nil t)
-        (goto-char (match-beginning 0))
-        ;; Ensure that \citeprocitem is defined for citeproc-el.
-        (insert "\\makeatletter\n\\newcommand{\\citeprocitem}[2]{\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}\n\\makeatother\n\n")
-        ;; Ensure there is a \usepackage{hanging} somewhere or add one.
-        (let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{hanging}")))
-          (unless (re-search-backward re nil t)
-            (insert "\\usepackage[notquote]{hanging}\n"))))
+	(goto-char (match-beginning 0))
+	;; Insert the CSL-specific parts of the LaTeX preamble.
+	(insert (org-cite-csl--generate-latex-preamble info)))
       (buffer-string))))
 
 \f
-- 
2.25.1


^ permalink raw reply related	[relevance 4%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-29  2:36  8%                     ` Ihor Radchenko
@ 2022-11-13 17:01  8%                       ` Max Nikulin
  0 siblings, 0 replies; 200+ results
From: Max Nikulin @ 2022-11-13 17:01 UTC (permalink / raw)
  To: emacs-orgmode

On 29/10/2022 09:36, Ihor Radchenko wrote:
> Ihor Radchenko writes:
> 
>> Then [0pt] should it be. At least for now, before we have a cleaner
>> solution.
>>
>> See the attached patch.
> 
> Applied onto main.
> https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=b93a61af9c93d21c56cf883630e52f36076e40bd
> 
> I will look into filtering out unnecessary [0pt] instances later.
> The patch here is more urgent as it avoids the known case of breakage.

Tabularray became aware of \empty:
https://github.com/lvjr/tabularray/issues/328

So in future this command may be used instead of [0pt].



^ permalink raw reply	[relevance 8%]

* Re: [PATCH] oc-csl: Improve LaTeX bibliography formatting
  2022-11-06  9:42  5% [PATCH] oc-csl: Improve LaTeX bibliography formatting András Simonyi
@ 2022-11-07  2:47  0% ` Ihor Radchenko
    0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-11-07  2:47 UTC (permalink / raw)
  To: András Simonyi; +Cc: emacs-orgmode list

András Simonyi <andras.simonyi@gmail.com> writes:

> the attached patch substantially improves the formatting of CSL-based
> bibliographies in LaTeX export by supporting in-style formatting
> settings that were previously ignored, most importantly,
> 'second-field-align', which is typically used for numeric styles such
> as ieee.csl.
>
> I'm sending this while another oc-csl patch (about affix and locator
> formatting) is still under discussion because I consider it a priority
> for the 9.6 release. (Not supporting those formatting settings
> rendered a large number of styles, some of them pretty popular, close
> to being unusable.)

Thanks for the patch!

Please, document the new customization in ORG-NEWS.
Also, it would be nice to describe CSL usage and tweaks in the manual.

> +;; The following was inspired by and mostly follows how Pandoc's
> +;; (<https://github.com/jgm/pandoc>) default LaTeX template handles
> +;; CSL output.  Many thanks to the author, John MacFarlane!
> +(defcustom org-cite-csl-latex-preamble
> +  "\\usepackage{calc}
> +\\newlength{\\cslhangindent}
> +\\setlength{\\cslhangindent}{[CSL-HANGINDENT]}
> +\\newlength{\\csllabelsep}
> +\\setlength{\\csllabelsep}{[CSL-LABELSEP]}
> +\\newlength{\\csllabelwidth}
> +\\setlength{\\csllabelwidth}{[CSL-LABELWIDTH-PER-CHAR] * [CSL-MAXLABEL-CHARS]}
> +\\newenvironment{citeprocbib}[2] % 1st arg. is hanging-indent, 2nd entry spacing.
> + {% By default, paragraphs are not indented.
> +  \\setlength{\\parindent}{0pt}
> +  % Hanging indent is turned on when first argument is 1.
> +  \\ifodd #1
> +  \\let\\oldpar\\par
> +  \\def\\par{\\hangindent=\\cslhangindent\\oldpar}
> +  \\fi
> +  % Set entry spacing based on the second argument.
> +  \\setlength{\\parskip}{\\parskip +  #2\\baselineskip}
> + }%
> + {}
> +\\newcommand{\\cslblock}[1]{#1\\hfill\\break}
> +\\newcommand{\\cslleftmargin}[1]{\\parbox[t]{\\csllabelsep + \\csllabelwidth}{#1}}
> +\\newcommand{\\cslrightinline}[1]
> +  {\\parbox[t]{\\linewidth - \\csllabelsep - \\csllabelwidth}{#1}\\break}
> +\\newcommand{\\cslindent}[1]{\\hspace{\\cslhangindent}#1}
> +\\makeatletter
> +\\newcommand{\\citeprocitem}[2]
> + {\\protect\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}
> +\\makeatother"
> +  "LaTeX preamble content inserted by the `csl' citation processor.
> +
> +The placeholders [CSL-HANGINDENT], [CSL-LABELSEP],
> +[CSL-LABELWIDTH-PER-CHAR] and [CSL-MAXLABEL-CHARS] are replaced,
> +respectively, by the contents of the customizable variables
> +`org-cite-csl-latex-hanging-indent', `org-cite-csl-latex-label-separator',
> +`org-cite-csl-latex-label-width-per-char', and the maximal label length
> +in the bibliography measured in characters."
> +  :group 'org-cite
> +  :type 'string
> +  :package-version '(Org . "9.6"))
> +

I have two comments here:
1. Where are all these new commands coming from? They are not used
   directly in the code. Are you tweaking citeproc.el output this way? May
   it be better to use customizations provided by citeproc.el itself?
2. You are declaring this variable as defcustom, but it is not clear
   what is going to happen if the user changes it. It is not how to
   change this template in meaningful ways either.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 0%]

* [PATCH] oc-csl: Improve LaTeX bibliography formatting
@ 2022-11-06  9:42  5% András Simonyi
  2022-11-07  2:47  0% ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: András Simonyi @ 2022-11-06  9:42 UTC (permalink / raw)
  To: emacs-orgmode list

[-- Attachment #1: Type: text/plain, Size: 658 bytes --]

Dear All,

the attached patch substantially improves the formatting of CSL-based
bibliographies in LaTeX export by supporting in-style formatting
settings that were previously ignored, most importantly,
'second-field-align', which is typically used for numeric styles such
as ieee.csl.

I'm sending this while another oc-csl patch (about affix and locator
formatting) is still under discussion because I consider it a priority
for the 9.6 release. (Not supporting those formatting settings
rendered a large number of styles, some of them pretty popular, close
to being unusable.)

Thanks in advance for your feedback!

best wishes,
András

[-- Attachment #2: 0001-oc-csl-Improve-LaTeX-bibliography-formatting.patch --]
[-- Type: text/x-patch, Size: 6831 bytes --]

From bc92683a6326e7f97093b401caf453a76b76ba46 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A1s=20Simonyi?= <andras.simonyi@gmail.com>
Date: Sun, 2 Oct 2022 19:20:36 +0200
Subject: [PATCH] oc-csl: Improve LaTeX bibliography formatting

* lisp/oc-csl.el (org-cite-csl--output-format): Use the dedicated
'org-latex' citeproc formatter to export references in LaTeX.
(org-cite-csl-latex-preamble, org-cite-csl--generate-latex-preamble,
org-cite-csl-finalizer): Insert a preamble fragment compatible with
the 'org-latex' citeproc formatter.
(org-cite-csl-latex-label-separator,
org-cite-csl-latex-label-width-per-char): Introduce additional
variables to control bibliography formatting.
---
 lisp/oc-csl.el | 98 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 83 insertions(+), 15 deletions(-)

diff --git a/lisp/oc-csl.el b/lisp/oc-csl.el
index 1ccb74e92..1807efaea 100644
--- a/lisp/oc-csl.el
+++ b/lisp/oc-csl.el
@@ -214,6 +214,68 @@ Used only when `second-field-align' is activated by the used CSL style."
   :type 'string
   :safe #'stringp)
 
+(defcustom org-cite-csl-latex-label-separator "0.6em"
+  "Distance between citation label and bibliography item for LaTeX
+output in valid LaTeX units.  Used only when `second-field-align'
+is activated by the used CSL style."
+  :group 'org-cite
+  :package-version '(Org . "9.6")
+  :type 'string
+  :safe #'stringp)
+
+(defcustom org-cite-csl-latex-label-width-per-char "0.45em"
+  "Character width in LaTeX units for calculating entry label widths.
+Used only when `second-field-align' is activated by the used CSL
+style."
+  :group 'org-cite
+  :package-version '(Org . "9.6")
+  :type 'string
+  :safe #'stringp)
+
+;; The following was inspired by and mostly follows how Pandoc's
+;; (<https://github.com/jgm/pandoc>) default LaTeX template handles
+;; CSL output.  Many thanks to the author, John MacFarlane!
+(defcustom org-cite-csl-latex-preamble
+  "\\usepackage{calc}
+\\newlength{\\cslhangindent}
+\\setlength{\\cslhangindent}{[CSL-HANGINDENT]}
+\\newlength{\\csllabelsep}
+\\setlength{\\csllabelsep}{[CSL-LABELSEP]}
+\\newlength{\\csllabelwidth}
+\\setlength{\\csllabelwidth}{[CSL-LABELWIDTH-PER-CHAR] * [CSL-MAXLABEL-CHARS]}
+\\newenvironment{citeprocbib}[2] % 1st arg. is hanging-indent, 2nd entry spacing.
+ {% By default, paragraphs are not indented.
+  \\setlength{\\parindent}{0pt}
+  % Hanging indent is turned on when first argument is 1.
+  \\ifodd #1
+  \\let\\oldpar\\par
+  \\def\\par{\\hangindent=\\cslhangindent\\oldpar}
+  \\fi
+  % Set entry spacing based on the second argument.
+  \\setlength{\\parskip}{\\parskip +  #2\\baselineskip}
+ }%
+ {}
+\\newcommand{\\cslblock}[1]{#1\\hfill\\break}
+\\newcommand{\\cslleftmargin}[1]{\\parbox[t]{\\csllabelsep + \\csllabelwidth}{#1}}
+\\newcommand{\\cslrightinline}[1]
+  {\\parbox[t]{\\linewidth - \\csllabelsep - \\csllabelwidth}{#1}\\break}
+\\newcommand{\\cslindent}[1]{\\hspace{\\cslhangindent}#1}
+\\makeatletter
+\\newcommand{\\citeprocitem}[2]
+ {\\protect\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}
+\\makeatother"
+  "LaTeX preamble content inserted by the `csl' citation processor.
+
+The placeholders [CSL-HANGINDENT], [CSL-LABELSEP],
+[CSL-LABELWIDTH-PER-CHAR] and [CSL-MAXLABEL-CHARS] are replaced,
+respectively, by the contents of the customizable variables
+`org-cite-csl-latex-hanging-indent', `org-cite-csl-latex-label-separator',
+`org-cite-csl-latex-label-width-per-char', and the maximal label length
+in the bibliography measured in characters."
+  :group 'org-cite
+  :type 'string
+  :package-version '(Org . "9.6"))
+
 \f
 ;;; Internal variables
 (defconst org-cite-csl--etc-dir
@@ -413,7 +475,7 @@ corresponding to one of the output formats supported by Citeproc: `html',
   (let ((backend (plist-get info :back-end)))
     (cond
      ((org-export-derived-backend-p backend 'html) 'html)
-     ((org-export-derived-backend-p backend 'latex) 'latex)
+     ((org-export-derived-backend-p backend 'latex) 'org-latex)
      (t 'org))))
 
 (defun org-cite-csl--style-file (info)
@@ -670,6 +732,21 @@ value is the bibliography as rendered by Citeproc."
             (plist-put info :cite-citeproc-rendered-bibliographies result)
             result)))))
 
+(defun org-cite-csl--generate-latex-preamble (info)
+  "Generate the CSL-related part of the LaTeX preamble.
+INFO is the export state, as a property list."
+  (let* ((parameters (cadr (org-cite-csl--rendered-bibliographies info)))
+	 (max-offset (cdr (assq 'max-offset parameters)))
+	 (result org-cite-csl-latex-preamble))
+    (map-do (lambda (placeholder replacement)
+	      (when (string-match placeholder result)
+		(setq result (replace-match replacement t t result))))
+	    `("\\[CSL-HANGINDENT\\]" ,org-cite-csl-latex-hanging-indent
+	      "\\[CSL-LABELSEP\\]" ,org-cite-csl-latex-label-separator
+	      "\\[CSL-LABELWIDTH-PER-CHAR\\]" ,org-cite-csl-latex-label-width-per-char
+	      "\\[CSL-MAXLABEL-CHARS\\]" ,(number-to-string max-offset)))
+    result))
+
 \f
 ;;; Export capability
 (defun org-cite-csl-render-citation (citation _style _backend info)
@@ -714,12 +791,7 @@ INFO is the export state, as a property list."
               org-cite-csl-html-hanging-indent
               org-cite-csl-html-hanging-indent))
         output))
-      ('latex
-       (if (cdr (assq 'hanging-indent parameters))
-           (format "\\begin{hangparas}{%s}{1}\n%s\n\\end{hangparas}"
-                   org-cite-csl-latex-hanging-indent
-                   output)
-         output))
+      ('org-latex output)
       (_
        ;; Parse Org output to re-export it during the regular export
        ;; process.
@@ -730,18 +802,14 @@ INFO is the export state, as a property list."
 OUTPUT is the export document, as a string.  INFO is the export state, as a
 property list."
   (org-cite-csl--barf-without-citeproc)
-  (if (not (eq 'latex (org-cite-csl--output-format info)))
+  (if (not (eq 'org-latex (org-cite-csl--output-format info)))
       output
     (with-temp-buffer
       (save-excursion (insert output))
       (when (search-forward "\\begin{document}" nil t)
-        (goto-char (match-beginning 0))
-        ;; Ensure that \citeprocitem is defined for citeproc-el.
-        (insert "\\makeatletter\n\\newcommand{\\citeprocitem}[2]{\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}\n\\makeatother\n\n")
-        ;; Ensure there is a \usepackage{hanging} somewhere or add one.
-        (let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{hanging}")))
-          (unless (re-search-backward re nil t)
-            (insert "\\usepackage[notquote]{hanging}\n"))))
+	(goto-char (match-beginning 0))
+	;; Insert the CSL-specific parts of the LaTeX preamble.
+	(insert (org-cite-csl--generate-latex-preamble info)))
       (buffer-string))))
 
 \f
-- 
2.25.1


^ permalink raw reply related	[relevance 5%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-04  5:40  8%                                               ` Max Nikulin
@ 2022-11-05  5:30 11%                                                 ` Ihor Radchenko
  0 siblings, 0 replies; 200+ results
From: Ihor Radchenko @ 2022-11-05  5:30 UTC (permalink / raw)
  To: Max Nikulin, Daniel Fleischer; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

>>> I still believe that
>>>
>>>       something\\[0pt]%__ORG_EXPORT__
>>>
>>> is quite safe to remove (depending on the following character) and
>>> unlikely harmful if remained for some reason.
>> 
>> What about the side effect you mentioned in a previous email?
>> 
>>> 		   TeX reads
>>>
>>> 		   "a% comment
>>> 		      b"
>>>
>>> 		   as "ab", dropping newline and starting spaces.
>
> Unlike in Org, in TeX "a\\b" still contains a line break. Besides exotic 
> packages and user setups it should just work. After all, during normal 
> operation all "%__ORG_EXPORT__" should be stripped by a filter. They are 
> just marks where a decision is necessary whether to retain "[0pt]" or to 
> remove it.

Thanks for the clarification.

So, we can

1. Change org-latex-line-break-safe to "\\\\[0pt]%__ORG_EXPORT__",
   making it unique to distinguish Org-generated line breaks.
2. Establish a regexp criterion when it is safe to strip
   "[0pt]%__ORG_EXPORT__" from the page break (I am still unsure what
   will be the most reliable criteria here). If not safe, we just strip
   the "%__ORG_EXPORT__" part.
3. Write a filter that replaces the above from final output.
   Note: If we go __ORG_EXPORT__ way, it might be safe to leave the
   filter on by default as long as we can find a really robust criteria
   on when it is safe to drop [0pt] part.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 11%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-04  4:23  0%                                             ` Ihor Radchenko
@ 2022-11-04  5:40  8%                                               ` Max Nikulin
  2022-11-05  5:30 11%                                                 ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2022-11-04  5:40 UTC (permalink / raw)
  To: emacs-orgmode

On 04/11/2022 11:23, Ihor Radchenko wrote:
> Max Nikulin writes:
>>> Ihor Radchenko writes:
>>>
>>>> These arguments mean that auto-cleaning \\[0pt] is not always safe and
>>>> may be a subject of surrounding LaTeX context.
>>
>> I still believe that
>>
>>       something\\[0pt]%__ORG_EXPORT__
>>
>> is quite safe to remove (depending on the following character) and
>> unlikely harmful if remained for some reason.
> 
> What about the side effect you mentioned in a previous email?
> 
>> 		   TeX reads
>>
>> 		   "a% comment
>> 		      b"
>>
>> 		   as "ab", dropping newline and starting spaces.

Unlike in Org, in TeX "a\\b" still contains a line break. Besides exotic 
packages and user setups it should just work. After all, during normal 
operation all "%__ORG_EXPORT__" should be stripped by a filter. They are 
just marks where a decision is necessary whether to retain "[0pt]" or to 
remove it.

On 03/11/2022 22:48, Juan Manuel Macías wrote:
> Max Nikulin writes:
> 
>> I have not managed to convince even the tabularray developer. And I
>> have not tried to find a way to reach more LaTeX developers.
> 
> I think that people from the LaTeX team and the authors of the most
> popular packages are often very active on tex.stackexchange.com

Stackexchange is for questions, not for discussions and bugs. At certain 
point I was going to ask a question there, I even prepared a draft. 
After that I decided to try a command expanding to nothing and found 
\empty. I was not aware that tabularray uses a different approach to 
parsing.

> And the repo on GitHub for the LaTeX project: https://github.com/latex3

https://github.com/latex3/latex3/issues may be an appropriate place, 
thank you.





^ permalink raw reply	[relevance 8%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-03 15:33 10%                                           ` Max Nikulin
@ 2022-11-04  4:23  0%                                             ` Ihor Radchenko
  2022-11-04  5:40  8%                                               ` Max Nikulin
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-11-04  4:23 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

>> Ihor Radchenko writes:
>> 
>>> These arguments mean that auto-cleaning \\[0pt] is not always safe and
>>> may be a subject of surrounding LaTeX context.
>
> I still believe that
>
>      something\\[0pt]%__ORG_EXPORT__
>
> is quite safe to remove (depending on the following character) and 
> unlikely harmful if remained for some reason.

What about the side effect you mentioned in a previous email?

>		   TeX reads
>
>		   "a% comment
>		      b"
>
>		   as "ab", dropping newline and starting spaces.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 0%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-03 15:00  9%                                         ` Juan Manuel Macías
@ 2022-11-03 15:33 10%                                           ` Max Nikulin
  2022-11-04  4:23  0%                                             ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2022-11-03 15:33 UTC (permalink / raw)
  To: emacs-orgmode

> Ihor Radchenko writes:
> 
>> These arguments mean that auto-cleaning \\[0pt] is not always safe and
>> may be a subject of surrounding LaTeX context.

I still believe that

     something\\[0pt]%__ORG_EXPORT__

is quite safe to remove (depending on the following character) and 
unlikely harmful if remained for some reason. Even tabularray 
regexp-based parser ignores comments. To be perfect, 
"\\[0pt]%__ORG_EXPORT__" emitted by user code should be escaped to e.g. 
"\\[0pd]%__ORG_EXPORT____ORG_EXPORT__", but I have no idea if it can be 
implemented in a reliable way.

An alternative is a new export framework.

On 03/11/2022 22:00, Juan Manuel Macías wrote:
> 
> BTW, I also hope that one day this LaTeX problem, which has been there
> for so many years, will be solved (because it should be considered a
> LaTeX bug, or a LaTeX design flaw, as Maxim commented in another
> message).

I have not managed to convince even the tabularray developer. And I have 
not tried to find a way to reach more LaTeX developers.





^ permalink raw reply	[relevance 10%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-03  6:15 10%                                       ` Ihor Radchenko
@ 2022-11-03 15:00  9%                                         ` Juan Manuel Macías
  2022-11-03 15:33 10%                                           ` Max Nikulin
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2022-11-03 15:00 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Max Nikulin, emacs-orgmode

Ihor Radchenko writes:

> These arguments mean that auto-cleaning \\[0pt] is not always safe and
> may be a subject of surrounding LaTeX context. Moreover, there is no
> clear alternative to \\[0pt] that is guaranteed to work.
> Thus, the whole idea with cleaning up the generated LaTeX cannot be
> enabled by default, and I am not even sure if it is something we want to
> implement in the core.
>
> Juan, maybe you have some good alternative suggestions?

I'm afraid not. I've been trying to follow the thread these past few
days and frankly I can't think of anything beyond all the options that
have already been discussed.

I agree that the safest solution (or the least compromised, depending on
how we look at it) is to add [0pt] in all cases. I believe this should
not bring any unexpected consequences. At least I've tried all the
tabular environments related packages that I know of and there don't
seem to be any problems. And in the case of the verse package and verse
numberings, the solution is ad hoc with the patch that I have planned (I
hope to find a gap these days to finish it and test it...): The idea of
the patch is to replace the current separation between stanzas that Org
adds (\vspace) with a white line, and (only) in that case it would be
necessary to ensure that the last verse of the stanza ends in \\!.

On the other hand, if 'factory-cleaning' unnecessary instances of [0pt]
is going to be problematic, I also agree not to add that action to the
exporter. I think it would be better to leave these things up to the
users, depending on their use cases. After all, it is not difficult to
do it using a specific export filter. Maybe add some tips and examples
of basic filters in the documentation, especially for users who don't
have a lot of experience writing filters?

BTW, I also hope that one day this LaTeX problem, which has been there
for so many years, will be solved (because it should be considered a
LaTeX bug, or a LaTeX design flaw, as Maxim commented in another
message). 

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 9%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-02 15:27  0%                                     ` Max Nikulin
@ 2022-11-03  6:15 10%                                       ` Ihor Radchenko
  2022-11-03 15:00  9%                                         ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-11-03  6:15 UTC (permalink / raw)
  To: Max Nikulin, Juan Manuel Macías; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

> On 02/11/2022 13:46, Ihor Radchenko wrote:
>> Ihor Radchenko writes:
>> 
>>> Should we, instead of using exact "\\[0pt]" string for line breaks,
>>> define a new LaTeX command and then clean it up? This will distinguish
>>> between \\[0pt] added by users explicitly and the ones generated
>>> automatically by Org.
>> 
>> I guess it will not work for that fancy table package we discussed
>> above.
>
> tabularray package will require \NewTableCommand
>
>> Maybe the Max's idea with "\\[0pt]%some comment indicator"?
>> I am just worried that % does have side effects in LaTeX.
>
> TeX reads
>
> "a% comment
>    b"
>
> as "ab", dropping newline and starting spaces. Of course, advanced users 
> may redefine category of "%" from comment to something else (regular 
> character, command prefix like \, etc.) like it is done inside verbatim 
> environment.

These arguments mean that auto-cleaning \\[0pt] is not always safe and
may be a subject of surrounding LaTeX context. Moreover, there is no
clear alternative to \\[0pt] that is guaranteed to work.
Thus, the whole idea with cleaning up the generated LaTeX cannot be
enabled by default, and I am not even sure if it is something we want to
implement in the core.

Juan, maybe you have some good alternative suggestions?

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 10%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-02  6:46  8%                                   ` Ihor Radchenko
@ 2022-11-02 15:27  0%                                     ` Max Nikulin
  2022-11-03  6:15 10%                                       ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2022-11-02 15:27 UTC (permalink / raw)
  To: emacs-orgmode

On 02/11/2022 13:46, Ihor Radchenko wrote:
> Ihor Radchenko writes:
> 
>> Should we, instead of using exact "\\[0pt]" string for line breaks,
>> define a new LaTeX command and then clean it up? This will distinguish
>> between \\[0pt] added by users explicitly and the ones generated
>> automatically by Org.
> 
> I guess it will not work for that fancy table package we discussed
> above.

tabularray package will require \NewTableCommand

> Maybe the Max's idea with "\\[0pt]%some comment indicator"?
> I am just worried that % does have side effects in LaTeX.

TeX reads

"a% comment
   b"

as "ab", dropping newline and starting spaces. Of course, advanced users 
may redefine category of "%" from comment to something else (regular 
character, command prefix like \, etc.) like it is done inside verbatim 
environment.






^ permalink raw reply	[relevance 0%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-02  6:44 11%                                 ` Ihor Radchenko
@ 2022-11-02  6:46  8%                                   ` Ihor Radchenko
  2022-11-02 15:27  0%                                     ` Max Nikulin
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-11-02  6:46 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Ihor Radchenko <yantar92@posteo.net> writes:

> Should we, instead of using exact "\\[0pt]" string for line breaks,
> define a new LaTeX command and then clean it up? This will distinguish
> between \\[0pt] added by users explicitly and the ones generated
> automatically by Org.

I guess it will not work for that fancy table package we discussed
above. Maybe the Max's idea with "\\[0pt]%some comment indicator"?
I am just worried that % does have side effects in LaTeX.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 8%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-01 16:07  9%                               ` Max Nikulin
@ 2022-11-02  6:44 11%                                 ` Ihor Radchenko
  2022-11-02  6:46  8%                                   ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-11-02  6:44 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

> Another corner case when "\\[0pt]\n" should not be blindly replaced to 
> "\\\n" (I do not escape "\"). Imagine that you are going to describe 
> this optimizing filter
>
> ---- >8 ----
> Optimizing filter will replace
> #+begin_example
> First\\[0pt]
> Second
> #+end_example
> with
> #+begin_example
> First\\
> Second
> #+end_example
> ---- 8< -----

This is a strong argument against auto-removing the \\[0pt].
Should we, instead of using exact "\\[0pt]" string for line breaks,
define a new LaTeX command and then clean it up? This will distinguish
between \\[0pt] added by users explicitly and the ones generated
automatically by Org.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 11%]

* Re: Line breaks and brackets in LaTeX export
  2022-11-01  1:51  0%                             ` Ihor Radchenko
@ 2022-11-01 16:07  9%                               ` Max Nikulin
  2022-11-02  6:44 11%                                 ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2022-11-01 16:07 UTC (permalink / raw)
  To: emacs-orgmode

On 01/11/2022 08:51, Ihor Radchenko wrote:
> Max Nikulin writes:
> 
>> On 22/10/2022 12:15, Ihor Radchenko wrote:
>>> as long as the next line does not match
>>> "^[ \t]*\\["
>>
>> Verse package defines \\! and \\>.
>>
>> The only precaution that search pattern should ignore \\\[0pt]\] that is
>> a display equation "0pt]"
> 
> Can you please elaborate?

LaTeX verse package require "\\!" as stanza separator to get proper line 
count, so square bracket on the next line is not the only character that 
may change meaning of "\\". So "[*!>" (depending on context) should be 
handled.

Search pattern should not match odd number of backslashes. It is a 
common mistake to not care what character precedes the pattern. 
Accordingly to Org syntax \\ line break may appear at the end of line 
only, but a user may add for some reason @@latex:...@.

Another corner case when "\\[0pt]\n" should not be blindly replaced to 
"\\\n" (I do not escape "\"). Imagine that you are going to describe 
this optimizing filter

---- >8 ----
Optimizing filter will replace
#+begin_example
First\\[0pt]
Second
#+end_example
with
#+begin_example
First\\
Second
#+end_example
---- 8< -----

>>> 2. Modify org-latex-template to replace unnecessary occurrences of
>>>      "\\[0pt]" in CONTENTS when org-latex-compact-latex (you may propose
>>>      other defcustom names) is non-nil.
>>
>> I believe, it is better to introduce a list of filter functions that may
>> perform such optimizing.
> 
> I don't think so. Users can already define filters. What we discuss here
> is a built-in filter. It should be separate from user customization and
> only expose on/off options.

If a separate defcustom is used for each built-in filter then it will be 
inconvenient to review which filters are active from easy customization UI.

It might be better to use single defcustom of list type allowing to 
disable particular built-in filters and to add user filters and to 
define their order in respect to built-in ones. I am unsure concerning 
convenient enough UI.





^ permalink raw reply	[relevance 9%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-22 15:55 10%                           ` Max Nikulin
@ 2022-11-01  1:51  0%                             ` Ihor Radchenko
  2022-11-01 16:07  9%                               ` Max Nikulin
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-11-01  1:51 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

> On 22/10/2022 12:15, Ihor Radchenko wrote:
>> as long as the next line does not match
>> "^[ \t]*\\["
>
> Verse package defines \\! and \\>.
>
> The only precaution that search pattern should ignore \\\[0pt]\] that is 
> a display equation "0pt]"

Can you please elaborate?

>> 2. Modify org-latex-template to replace unnecessary occurrences of
>>     "\\[0pt]" in CONTENTS when org-latex-compact-latex (you may propose
>>     other defcustom names) is non-nil.
>
> I believe, it is better to introduce a list of filter functions that may 
> perform such optimizing.

I don't think so. Users can already define filters. What we discuss here
is a built-in filter. It should be separate from user customization and
only expose on/off options.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 0%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-19  3:57 33%                   ` Ihor Radchenko
  2022-10-19  5:11 11%                     ` Max Nikulin
@ 2022-10-29  2:36  8%                     ` Ihor Radchenko
  2022-11-13 17:01  8%                       ` Max Nikulin
  1 sibling, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-10-29  2:36 UTC (permalink / raw)
  To: Juan Manuel Macías
  Cc: Daniel Fleischer, Max Nikulin, emacs-orgmode, Ihor Radchenko,
	Vikas Rawal

Ihor Radchenko <yantar92@posteo.net> writes:

> Then [0pt] should it be. At least for now, before we have a cleaner
> solution.
>
> See the attached patch.

Applied onto main.
https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=b93a61af9c93d21c56cf883630e52f36076e40bd

I will look into filtering out unnecessary [0pt] instances later.
The patch here is more urgent as it avoids the known case of breakage.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 8%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-22  5:15 11%                         ` Ihor Radchenko
  2022-10-22 12:26  0%                           ` Juan Manuel Macías
@ 2022-10-22 15:55 10%                           ` Max Nikulin
  2022-11-01  1:51  0%                             ` Ihor Radchenko
  1 sibling, 1 reply; 200+ results
From: Max Nikulin @ 2022-10-22 15:55 UTC (permalink / raw)
  To: emacs-orgmode

On 22/10/2022 12:15, Ihor Radchenko wrote:
> as long as the next line does not match
> "^[ \t]*\\["

Verse package defines \\! and \\>.

The only precaution that search pattern should ignore \\\[0pt]\] that is 
a display equation "0pt]"

> I propose the following:
> 1. Merge my patch with \\[0pt] safe page breaks
> 2. Modify org-latex-template to replace unnecessary occurrences of
>     "\\[0pt]" in CONTENTS when org-latex-compact-latex (you may propose
>     other defcustom names) is non-nil.

I believe, it is better to introduce a list of filter functions that may 
perform such optimizing.

The only problem that I see with such approach is that if defined as 
defcustom then users changed its value will not see default filters 
added in new Org version. If an alist mapping hook name to 
enabled/disabled state is used then I am unsure how to determine order 
of hooks during mixing of standard and user defined functions. I raised 
a similar question during discussion of org-file-apps.

I do not have a better proposal.




^ permalink raw reply	[relevance 10%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-22  5:15 11%                         ` Ihor Radchenko
@ 2022-10-22 12:26  0%                           ` Juan Manuel Macías
  2022-10-22 15:55 10%                           ` Max Nikulin
  1 sibling, 0 replies; 200+ results
From: Juan Manuel Macías @ 2022-10-22 12:26 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Max Nikulin, emacs-orgmode

Ihor Radchenko writes:

> Or, to be completely safe, we can introduce a defcustom that will
> control such clean-up (clean up by default).
>
> I propose the following:
> 1. Merge my patch with \\[0pt] safe page breaks
> 2. Modify org-latex-template to replace unnecessary occurrences of
>    "\\[0pt]" in CONTENTS when org-latex-compact-latex (you may propose
>    other defcustom names) is non-nil.
>
> WDYT?

+1

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 0%]

* Re: Line breaks and brackets in LaTeX export
  @ 2022-10-22  5:15 11%                         ` Ihor Radchenko
  2022-10-22 12:26  0%                           ` Juan Manuel Macías
  2022-10-22 15:55 10%                           ` Max Nikulin
  0 siblings, 2 replies; 200+ results
From: Ihor Radchenko @ 2022-10-22  5:15 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

> Concerning element vs. exported text, consider a derived backend that 
> ignores italics markers if a paragraph has some attribute. Usually
>       Paragraph \\
>       \emph{[something]}
> does not cause any problem, however if italics is ignored it is an error
>       Paragraph\\
>       [something]
> That is why namely exported code of adjacent leaf node should be 
> examined. Ideally there should be a possibility to add some attributes 
> or properties to distinguish raw export snippet.

This is a valid example.

> Unfortunately it requires complete redesign of org-export.

Thinking about it more, we may actually do post-processing of the
exported text. Unless I miss something, constructs like "\\[0pt]\n" can
_always_ be replaced with "\\\n" as long as the next line does not match
"^[ \t]*\\[". Even when such construct is deliberately placed by the
user. There will be no difference in the generated pdf.

Or, to be completely safe, we can introduce a defcustom that will
control such clean-up (clean up by default).

I propose the following:
1. Merge my patch with \\[0pt] safe page breaks
2. Modify org-latex-template to replace unnecessary occurrences of
   "\\[0pt]" in CONTENTS when org-latex-compact-latex (you may propose
   other defcustom names) is non-nil.

WDYT?

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 11%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-21 16:38 10%                                 ` Max Nikulin
@ 2022-10-21 19:32  0%                                   ` Juan Manuel Macías
  0 siblings, 0 replies; 200+ results
From: Juan Manuel Macías @ 2022-10-21 19:32 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode, Ihor Radchenko

Max Nikulin writes:

> My impression is that tabularray has an ambitious goal to replace all
> current table packages. I have no idea if other packages will adopt
> similar approach with regexp-based parsing instead of usual expanding
> of TeX commands.

Yes, that's the impression I have too. Tabularray certainly solves a lot
of traditional LaTeX table problems (unfortunately not the one we're
dealing with). Time will tell if it also creates other new problems. In
any case, it brings a lot of flexibility to a part of LaTeX, tables,
that has always suffered from a certain constriction. We'll see what
happens. LaTeX is becoming very complex and now several layers coexist,
since the jump to LaTeX 3 is going to be gradual. On the other hand, I
don't know if the latex core developers have a cleaner \\ command in
their roadmap, without those absurd current problems (and that LaTeX has
been carrying for almost 40 years).

> I do not like necessity to add \NewTableCommand\empty{} to documents
> somehow (only if tabularray is loaded). I do not have an idea better
> than \\[0pt] and an optimizing filter to remove [0pt] in almost all
> cases.

I totally agree.

Best regards,

Juan Manuel 



^ permalink raw reply	[relevance 0%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-21  3:34  0%                               ` Ihor Radchenko
@ 2022-10-21 16:38 10%                                 ` Max Nikulin
  2022-10-21 19:32  0%                                   ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2022-10-21 16:38 UTC (permalink / raw)
  To: emacs-orgmode

On 21/10/2022 10:34, Ihor Radchenko wrote:
> Juan Manuel Macías writes:
> 
> I see the tabularray issue simply as an example that \empty is not as
> reliable as we thought. There might be other LaTeX packages throwing
> errors on \\\empty.

My impression is that tabularray has an ambitious goal to replace all 
current table packages. I have no idea if other packages will adopt 
similar approach with regexp-based parsing instead of usual expanding of 
TeX commands.

I do not like necessity to add \NewTableCommand\empty{} to documents 
somehow (only if tabularray is loaded). I do not have an idea better 
than \\[0pt] and an optimizing filter to remove [0pt] in almost all cases.




^ permalink raw reply	[relevance 10%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-20 16:55  6%                             ` Juan Manuel Macías
@ 2022-10-21  3:34  0%                               ` Ihor Radchenko
  2022-10-21 16:38 10%                                 ` Max Nikulin
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-10-21  3:34 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: Max Nikulin, emacs-orgmode, Ihor Radchenko

Juan Manuel Macías <maciaschain@posteo.net> writes:

> I've had a look at the thread. What do you think of that
> \NewTableCommand\empty{} workaround mentioned at
> https://github.com/lvjr/tabularray/discussions/321#discussioncomment-3920957?
>
> Since the \empty option only has problems in tabularray, maybe we could
> keep it, and put in the documentation some recommendations for
> tabularray users. I imagine they would have to add a @@latex:\empty@@
> before each row that follows a line. A bit laborious, I'm afraid.

I see the tabularray issue simply as an example that \empty is not as
reliable as we thought. There might be other LaTeX packages throwing
errors on \\\empty.

The proposed workaround may be enough for tabularray, but may not be for
other packages.

> Another possibility that occurs to me is that the string reserved for
> \empty, [0pt], etc., is a defcustom, with a value of \empty by default.
> So the user would choose what suits him best.

I do not think that users will clearly understand the purpose of such
defcustom. It is solving some very narrow edge case, and it is unclear
why we would need to advertise changing it in customize interface.

I'd prefer to keep it as defconst, but maybe mention in the docstring
that it can still be set to "\\empty" as another semi-safe value. At the
user's own risk.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 0%]

* Re: Line breaks and brackets in LaTeX export
  @ 2022-10-20 17:15  9%                   ` Max Nikulin
    0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2022-10-20 17:15 UTC (permalink / raw)
  To: Org Mode List; +Cc: Juan Manuel Macías

An argument in favor of \\[0pt] escaping. Unlike \empty, [0pt] is rather 
artificial, so such pattern may be removed (I hope in a safe way) by an 
export filter if it is not followed by a bracket or a star.

On 20/10/2022 12:07, Ihor Radchenko wrote:
> When transcoding children (e.g. table rows), the sibling rows can always
> be accessed using org-export-get-previous-element and
> org-export-get-next-element.

Decision if escaping is necessary should be based on export result, not 
on the source element.

> Max Nikulin writes:

>> As another approach text properties may be used as a communication
>> channel unless they are stripped by ox.
> 
> I am not sure what you are referring to. If modifying exported string,
> it will suffer from the same problems as your idea with comment.

It is a brain storm idea, I still unsure it is feasible.

I mean info "(elisp) Text Properties". I do not think they are usually 
ignored by filters. \\ substrings added by ox-latex may have some unique 
property. Export filter searches for occurrences of \\ to check if 
escaping is necessary, but it ignores particular location if the text 
does not have the specific property. I would prefer to mark output of 
export snippets with another property value and do not escape them. It 
is a kind of out of band communication. Unsure if text properties may be 
lost due to string operations in an exporter or vice versa to propagate 
to the source buffer.



^ permalink raw reply	[relevance 9%]

* Re: Line breaks and brackets in LaTeX export
  @ 2022-10-20 16:55  6%                             ` Juan Manuel Macías
  2022-10-21  3:34  0%                               ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2022-10-20 16:55 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode, Ihor Radchenko

Max Nikulin writes:

> I have started a discussion requesting for a \\-like command without
> optional arguments. Maybe somebody will suggest a better workaround
> instead.
> https://github.com/lvjr/tabularray/discussions/321

I've had a look at the thread. What do you think of that
\NewTableCommand\empty{} workaround mentioned at
https://github.com/lvjr/tabularray/discussions/321#discussioncomment-3920957?

Since the \empty option only has problems in tabularray, maybe we could
keep it, and put in the documentation some recommendations for
tabularray users. I imagine they would have to add a @@latex:\empty@@
before each row that follows a line. A bit laborious, I'm afraid.

Another possibility that occurs to me is that the string reserved for
\empty, [0pt], etc., is a defcustom, with a value of \empty by default.
So the user would choose what suits him best.

By the way (a little digression), I was curious to see if these age-old
LaTeX problems with line breaking exist in ConTeXt as well. Since I'm
completely unfamiliar with ConTeXt, the quickest thing to do has been to
see what code ox-context returns for the org tables. The answer is that
there are no such problems, and one can safely put a square bracket at
the beginning of a row. It is also true that the table syntax in ConTeXt
is radically different from that in LaTeX. And there is also no problem
if I put @@context:a\[b]@@. Some screenshots:

https://i.imgur.com/2k1TaU9.png

https://i.imgur.com/8i9qlEH.png

Many times I've been tempted to give ConTeXt a try, but I've always run
into two things: ConTeXt's perennially experimental status and a
horrible lack of documentation. In addition, backward compatibility is
not usually respected, since ConTeXt, although it is free software, does
not have community development as a priority, but rather the company
behind it, Pragma.

>> I've tried all the packages involved in tables that I can think of
>> (longtable, siunitx, tabularx, booktabs, array, and I don't know if I
>> forgot any) and in all of them the \empty solution works fine. It seems
>> that tabularray is the black sheep here.
>
> I think tabularray is unique with a regexp-based parser. I had a hope
> that new approach does not allow newline between \\ and its arguments,
> but unfortunately compatibility with older code is preserved in this
> aspect.
>
> From LaTeX companion I remember supertabular as an alternative for
> longtable, but I am unsure if it is alive yet.

True, I had forgotten about this package (I don't think I've ever used
it). It looks like it has a 2020 new version:

@manual{supertabular,
  title = {The \texttt{supertabular} package},
  subtitle = {A multi-page tables package},
  author = {Johannes L. Braams},
  date = {2020-02-02},
  version = {4.1g},
  license = {lppl1.3c},
  url = {https://mirror.ctan.org/macros/latex/contrib/supertabular},
  pkgurl = {https://ctan.org/pkg/supertabular},
  }

(bibtex entry obtained from: https://www.ctan.org/pkg/ctan-bibdata)


^ permalink raw reply	[relevance 6%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-19  5:11 11%                     ` Max Nikulin
@ 2022-10-19 11:16  7%                       ` Juan Manuel Macías
    0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2022-10-19 11:16 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode, Ihor Radchenko

Max Nikulin writes:

> Another recipe should be used:
>
> | / | < |                                 > |
> |   | a | b @@latex:\rule[-1em]{0pt}{1em}@@ |
> |   | c | d                                 |
>
> I believe that a more convenient way to override [0pt] to some other
> length for particular row should exist, but I have no idea which
> syntax should be used.

I think this new recipe you propose works fine, although I haven't
done a thorough test yet. In principle, it shouldn't be a problem.

By the way, now I remember that the package verse adds a series of extra
arguments to \\ (p. 6 in the documentation:
https://www.ctan.org/pkg/verse). As a user, the only way I can think of
to add arguments instead of [0pt] or \empty is by using a small export
filter to act on the final output. Perhaps putting something like
!!new-argument!! on the affected row/verse/line to guide the filter.

> As to tabulararray, I still consider it as an experimental package.
> Perhaps I will install a more modern container. I am curious what code
> handles \\[0pt]. Likely I should read docs to get impression related
> to design goals and approaches to implement them. The bug tracker of
> the project looks like an appropriate place to ask a question
> concerning \\ variant safe for dumb exporters.

Keep in mind that tabularray is a latex3 package and, in principle,
everything that is latex3 is here to stay. Certainly, it is a blessing
compared to the classic tabular environments, because it is tremendously
versatile. That is why it already has a significant number of users:
https://tex.stackexchange.com/questions/tagged/tabularray

And Org already provides what is necessary to use its syntax. I've had a
first look at tabularray.sty, but I'm not familiar enough with the new
LaTeX 3 syntax and, frankly, I'm lost...

I've tried all the packages involved in tables that I can think of
(longtable, siunitx, tabularx, booktabs, array, and I don't know if I
forgot any) and in all of them the \empty solution works fine. It seems
that tabularray is the black sheep here.

> For a while I have the following question. Is \\{} have the same
> effect on tabularray parser as \\\empty?

Throw an error before \hline.


^ permalink raw reply	[relevance 7%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-19  3:57 33%                   ` Ihor Radchenko
@ 2022-10-19  5:11 11%                     ` Max Nikulin
  2022-10-19 11:16  7%                       ` Juan Manuel Macías
  2022-10-29  2:36  8%                     ` Ihor Radchenko
  1 sibling, 1 reply; 200+ results
From: Max Nikulin @ 2022-10-19  5:11 UTC (permalink / raw)
  To: emacs-orgmode

On 19/10/2022 10:57, Ihor Radchenko wrote:
> Juan Manuel Macías writes:
>>
>> Today I have tried with the latest version of tabularray (2022C, the one
>> I tried yesterday was 2022A, included in TeX Live 2022), and the bad
>> results persist. Also, it now returns a compile error when an \empty
>> precedes a \hline. I suspect this package does a pretty drastic
>> redefinition of \\. The [0pt] option still works fine here, though.
> 
> Then [0pt] should it be. At least for now, before we have a cleaner
> solution.

It seems when I had a look into latex.ltx first time, I confused which 
branch is executed when length is less than or equal to zero and decided 
that it is the heavier \@xargarraycr. Actually \@yargarraycr do not 
really worry me, so degree of my objection concerning \\[0pt] 
significantly decreased.

\def\@argarraycr[#1]{%
   \ifnum0=`{\fi}${}\ifdim #1>\z@ \@xargarraycr{#1}\else
    \@yargarraycr{#1}\fi}

\def\@xargarraycr#1{\@tempdima #1\advance\@tempdima \dp \@arstrutbox
    \vrule \@height\z@ \@depth\@tempdima \@width\z@ \cr}
\def\@yargarraycr#1{\cr\noalign{\vskip #1}}

I have realized that

| / | <                                | > |
|   | a                                | b |
|   | @@latex:\noalign{\vskip 1em}@@ c | d |

is not a workaround to increase local interval between rows. It may 
cause disrupted vertical rules. Another recipe should be used:

| / | < |                                 > |
|   | a | b @@latex:\rule[-1em]{0pt}{1em}@@ |
|   | c | d                                 |

I believe that a more convenient way to override [0pt] to some other 
length for particular row should exist, but I have no idea which syntax 
should be used.

As to tabulararray, I still consider it as an experimental package. 
Perhaps I will install a more modern container. I am curious what code 
handles \\[0pt]. Likely I should read docs to get impression related to 
design goals and approaches to implement them. The bug tracker of the 
project looks like an appropriate place to ask a question concerning \\ 
variant safe for dumb exporters.

For a while I have the following question. Is \\{} have the same effect 
on tabularray parser as \\\empty?




^ permalink raw reply	[relevance 11%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-18 14:23  8%                 ` Juan Manuel Macías
@ 2022-10-19  3:57 33%                   ` Ihor Radchenko
  2022-10-19  5:11 11%                     ` Max Nikulin
  2022-10-29  2:36  8%                     ` Ihor Radchenko
  0 siblings, 2 replies; 200+ results
From: Ihor Radchenko @ 2022-10-19  3:57 UTC (permalink / raw)
  To: Juan Manuel Macías
  Cc: Daniel Fleischer, Max Nikulin, emacs-orgmode, Ihor Radchenko,
	Vikas Rawal

[-- Attachment #1: Type: text/plain, Size: 721 bytes --]

Juan Manuel Macías <maciaschain@posteo.net> writes:

>> It is easy to change \\\empty constant to \\[0pt] if necessary. I have
>> no objection either way. Though I do not feel like we are in rush. I'd
>> like to hear from ox-latex maintainer.
>
> Today I have tried with the latest version of tabularray (2022C, the one
> I tried yesterday was 2022A, included in TeX Live 2022), and the bad
> results persist. Also, it now returns a compile error when an \empty
> precedes a \hline. I suspect this package does a pretty drastic
> redefinition of \\. The [0pt] option still works fine here, though.

Then [0pt] should it be. At least for now, before we have a cleaner
solution.

See the attached patch.


[-- Attachment #2: 0001-org-latex-line-break-safe-Use-safer-value-of-0pt.patch --]
[-- Type: text/x-patch, Size: 4217 bytes --]

From b060f63078d65758f8fd2ab7725fbcf8b2de0057 Mon Sep 17 00:00:00 2001
Message-Id: <b060f63078d65758f8fd2ab7725fbcf8b2de0057.1666151751.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Wed, 19 Oct 2022 11:48:26 +0800
Subject: [PATCH] org-latex-line-break-safe: Use safer value of "\\[0pt]"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/ox-latex.el (org-latex-line-break-safe):
(org-latex-table-row):
Change \empty ending to explicit optional argument.  \empty still has
undesired side effects in some cases.

* testing/lisp/test-org-table.el (test-org-table/to-latex):
* testing/lisp/test-ox-latex.el (test-ox-latex/verse): Update tests.

Reported-by: Juan Manuel Macías <maciaschain@posteo.net>
Link: https://orgmode.org/list/87o7u9rz1a.fsf@posteo.net
---
 lisp/ox-latex.el               | 12 ++++++------
 testing/lisp/test-org-table.el |  6 +++---
 testing/lisp/test-ox-latex.el  | 12 ++++++------
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index dc8477d14..a5652fd78 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -278,17 +278,17 @@ (defconst org-latex-language-alist
 
 - `:lang-name' the actual name of the language.")
 
-(defconst org-latex-line-break-safe "\\\\\\empty"
+(defconst org-latex-line-break-safe "\\\\[0pt]"
   "Linebreak protecting the following [...].
 
-Without \"\\empty\" it would be interpreted as an optional argument to
+Without \"[0pt]\" it would be interpreted as an optional argument to
 the \\\\.
 
 This constant, for example, makes the below code not err:
 
 \\begin{tabular}{c|c}
-    [t] & s\\\\\\empty
-    [I] & A\\\\\\empty
+    [t] & s\\\\[0pt]
+    [I] & A\\\\[0pt]
     [m] & kg
 \\end{tabular}")
 
@@ -4005,9 +4005,9 @@ (defun org-latex-table-row (table-row contents info)
 			      (org-export-get-parent-table table-row) info))))
 	   (format "%s
 \\endfirsthead
-\\multicolumn{%d}{l}{%s} \\\\\\empty
+\\multicolumn{%d}{l}{%s} \\\\[0pt]
 %s
-%s \\\\\\empty\n
+%s \\\\[0pt]\n
 %s
 \\endhead
 %s\\multicolumn{%d}{r}{%s} \\\\
diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el
index 722c37ea4..573179878 100644
--- a/testing/lisp/test-org-table.el
+++ b/testing/lisp/test-org-table.el
@@ -1635,11 +1635,11 @@ (ert-deftest test-org-table/to-generic ()
 (ert-deftest test-org-table/to-latex ()
   "Test `orgtbl-to-latex' specifications."
   (should
-   (equal "\\begin{tabular}{l}\na\\\\\\empty\n\\end{tabular}"
+   (equal "\\begin{tabular}{l}\na\\\\[0pt]\n\\end{tabular}"
 	  (orgtbl-to-latex (org-table-to-lisp "| a |") nil)))
   ;; Test :environment parameter.
   (should
-   (equal "\\begin{tabularx}{l}\na\\\\\\empty\n\\end{tabularx}"
+   (equal "\\begin{tabularx}{l}\na\\\\[0pt]\n\\end{tabularx}"
 	  (orgtbl-to-latex (org-table-to-lisp "| a |")
 			   '(:environment "tabularx"))))
   ;; Test :booktabs parameter.
@@ -1648,7 +1648,7 @@ (ert-deftest test-org-table/to-latex ()
     "\\toprule" (orgtbl-to-latex (org-table-to-lisp "| a |") '(:booktabs t))))
   ;; Handle LaTeX snippets.
   (should
-   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\\\empty\n\\end{tabular}"
+   (equal "\\begin{tabular}{l}\n\\(x\\)\\\\[0pt]\n\\end{tabular}"
 	  (orgtbl-to-latex (org-table-to-lisp "| $x$ |") nil)))
   ;; Test pseudo objects and :raw parameter.
   (should
diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el
index 4fb9f2888..adb3a60ea 100644
--- a/testing/lisp/test-ox-latex.el
+++ b/testing/lisp/test-ox-latex.el
@@ -60,14 +60,14 @@ (ert-deftest test-ox-latex/verse ()
     (should
      (search-forward
       "\\begin{verse}
-lorem ipsum dolor\\\\\\empty
-lorem ipsum dolor\\\\\\empty
+lorem ipsum dolor\\\\[0pt]
+lorem ipsum dolor\\\\[0pt]
 \\vspace*{1em}
-lorem ipsum dolor\\\\\\empty
-lorem ipsum dolor\\\\\\empty
+lorem ipsum dolor\\\\[0pt]
+lorem ipsum dolor\\\\[0pt]
 \\vspace*{1em}
-lorem ipsum dolor\\\\\\empty
-lorem ipsum dolor\\\\\\empty
+lorem ipsum dolor\\\\[0pt]
+lorem ipsum dolor\\\\[0pt]
 \\end{verse}"))))
 
 (provide 'test-ox-latex)
-- 
2.35.1


[-- Attachment #3: Type: text/plain, Size: 225 bytes --]



-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

^ permalink raw reply related	[relevance 33%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-18  4:41  8%               ` Ihor Radchenko
@ 2022-10-18 14:23  8%                 ` Juan Manuel Macías
  2022-10-19  3:57 33%                   ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2022-10-18 14:23 UTC (permalink / raw)
  To: Ihor Radchenko
  Cc: Daniel Fleischer, Max Nikulin, emacs-orgmode, Ihor Radchenko,
	Vikas Rawal

Ihor Radchenko writes:

>> Assuming that there is currently no alternative to the non-selective
>> solution, and that, as you say, the presence of brackets may be more
>> common than I initially expected, if I had to choose between \empty and
>> [0pt], I would say that [0pt] is the safest, as it is an expected
>> argument to \\ and equals the default space. I can't think of any
>> unexpected results from this, but of course, it also depends on there
>> being no package redefining \\ with another argument structure on its
>> own. I think it would be a bad idea for a package developer, but LaTeX
>> (and the LaTeX packages) is horribly unpredictable.
>
> It is easy to change \\\empty constant to \\[0pt] if necessary. I have
> no objection either way. Though I do not feel like we are in rush. I'd
> like to hear from ox-latex maintainer.

Today I have tried with the latest version of tabularray (2022C, the one
I tried yesterday was 2022A, included in TeX Live 2022), and the bad
results persist. Also, it now returns a compile error when an \empty
precedes a \hline. I suspect this package does a pretty drastic
redefinition of \\. The [0pt] option still works fine here, though.


^ permalink raw reply	[relevance 8%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-17 18:04  8%             ` Juan Manuel Macías
@ 2022-10-18  4:41  8%               ` Ihor Radchenko
  2022-10-18 14:23  8%                 ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-10-18  4:41 UTC (permalink / raw)
  To: Juan Manuel Macías, Daniel Fleischer
  Cc: Max Nikulin, emacs-orgmode, Ihor Radchenko, Vikas Rawal

Juan Manuel Macías <maciaschain@posteo.net> writes:

> Assuming that there is currently no alternative to the non-selective
> solution, and that, as you say, the presence of brackets may be more
> common than I initially expected, if I had to choose between \empty and
> [0pt], I would say that [0pt] is the safest, as it is an expected
> argument to \\ and equals the default space. I can't think of any
> unexpected results from this, but of course, it also depends on there
> being no package redefining \\ with another argument structure on its
> own. I think it would be a bad idea for a package developer, but LaTeX
> (and the LaTeX packages) is horribly unpredictable.

It is easy to change \\\empty constant to \\[0pt] if necessary. I have
no objection either way. Though I do not feel like we are in rush. I'd
like to hear from ox-latex maintainer.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 8%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-17 16:46  5%           ` Max Nikulin
@ 2022-10-17 18:04  8%             ` Juan Manuel Macías
  2022-10-18  4:41  8%               ` Ihor Radchenko
    1 sibling, 1 reply; 200+ results
From: Juan Manuel Macías @ 2022-10-17 18:04 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode, Ihor Radchenko, Vikas Rawal

Max Nikulin writes:

> On 17/10/2022 22:01, Juan Manuel Macías wrote:
>> \documentclass{article}
>> \usepackage{tabularray}
>
> LaTeX I have installed is too old for this package. It is marked as
> "Experimental LaTeX3", so I am unsure, maybe you have found a bug in
> this package.
> https://ctan.org/pkg/tabularray

As I said, I don't use this package. Once I wanted to start using it,
because it has many interesting features, but I gave up on it because
this package does not (at the moment) have support for the CMYK color
space (necessary for print publication) with the xcolors package.

Maybe it's a bug, but the situation is that compiling the copied
examples as they are in the package manual, the result is correct (as it
is also shown in the manual); but adding an unexpected element (an
\empty on the last line) produces a bad result. Since you can't test the
package, I've taken this screenshot:

https://i.imgur.com/jkSHUMP.png

I think there is a tabularray user on the list, Vikas Rawal. In fact, I
also remember that I provided a patch so that he could use this package
in Org
(https://list.orgmode.org/CALtzAB1yM+uG_xHghCxTLRX5mgbzNvT5+PO=DuaBB28nCsVqEA@mail.gmail.com/).
I've cc'd him in case he wants to join the discussion.

> You believe that an issue with brackets is extremely rare. It may be
> true for humanitarian texts. For some users it may be a constant
> source of pain e.g. in the case of interval notation as [a,b]. I have
> already mentioned tables generated by code blocks, not typed directly.
> I can not say that I often need to export my notes, but I was afraid
> that I will be bitten by this bug because I may try to put dates close
> to left margin:
>
> - Something\\
>   [2022-10-17 Mon]
>
> By default dates wrapped into \textit, but it may be customized to
> just "%s".
>
> Selectively adding some workaround require complete reimplementation
> of exporters. I have some curiosity concerning pandoc approach, but I
> am unsure if I will reserve some time to read its code.

I see. If the selective solution is going to involve rewriting the
exporters, I find that it is unaffordable in the present circumstances.
It's a shame, because pandoc's solution seems ideal to me. What I
couldn't say is how pandoc does it and if it does it whenever expected,
because I use very little pandoc.

> I found \empty when I was looking for an approach with minimal
> overhead. I expect that e.g. \\[0pt] may have higher performance
> penalty since it is expanded to several commands. When the idea with
> "\\\relax" failed I was choosing between "\\{}" and "\\\empty". I
> decided that the latter minimizes risk to add spurious space.

Assuming that there is currently no alternative to the non-selective
solution, and that, as you say, the presence of brackets may be more
common than I initially expected, if I had to choose between \empty and
[0pt], I would say that [0pt] is the safest, as it is an expected
argument to \\ and equals the default space. I can't think of any
unexpected results from this, but of course, it also depends on there
being no package redefining \\ with another argument structure on its
own. I think it would be a bad idea for a package developer, but LaTeX
(and the LaTeX packages) is horribly unpredictable.

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 8%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-17 15:01  7%         ` Juan Manuel Macías
@ 2022-10-17 16:46  5%           ` Max Nikulin
  2022-10-17 18:04  8%             ` Juan Manuel Macías
    0 siblings, 2 replies; 200+ results
From: Max Nikulin @ 2022-10-17 16:46 UTC (permalink / raw)
  To: emacs-orgmode

On 17/10/2022 22:01, Juan Manuel Macías wrote:
> 
> \documentclass{article}
> \usepackage{tabularray}

LaTeX I have installed is too old for this package. It is marked as 
"Experimental LaTeX3", so I am unsure, maybe you have found a bug in 
this package.
https://ctan.org/pkg/tabularray

You believe that an issue with brackets is extremely rare. It may be 
true for humanitarian texts. For some users it may be a constant source 
of pain e.g. in the case of interval notation as [a,b]. I have already 
mentioned tables generated by code blocks, not typed directly. I can not 
say that I often need to export my notes, but I was afraid that I will 
be bitten by this bug because I may try to put dates close to left margin:

- Something\\
   [2022-10-17 Mon]

By default dates wrapped into \textit, but it may be customized to just 
"%s".

Selectively adding some workaround require complete reimplementation of 
exporters. I have some curiosity concerning pandoc approach, but I am 
unsure if I will reserve some time to read its code.

An idea how to avoid complete redesign: at first add something like
    %__ORG_PROTECT_NEWLINE__
after each \\, later at an optimizing pass remove the comment if next 
line does not start from a star or a square bracket, otherwise use some 
workaround, e.g. "{[}". \relax may be suitable as well (in the beginning 
of rows, not after \\).

I do not like approach with a custom command. It is effectively the same 
as adding \empty but \\ may be redefined by some packages, so I strongly 
prefer to keep \\ in exported markup. Redefining of \\ is a way to new 
issues. I do not feel firm ground with a command that will expand to \\. 
I am afraid that \\ may still consume following "[" unless \empty or its 
equivalent is added after it. I am completely unsure concerning 
tabularray parser that does not rely on TeX primitives.

I found \empty when I was looking for an approach with minimal overhead. 
I expect that e.g. \\[0pt] may have higher performance penalty since it 
is expanded to several commands. When the idea with "\\\relax" failed I 
was choosing between "\\{}" and "\\\empty". I decided that the latter 
minimizes risk to add spurious space.

Some problems:

I do not see a way to add some LaTeX code between table lines.

Semi-verbatim environment may be a source of new bugs. They may be 
rather selective in respect to what they consider a command and what is 
passed as raw text. tabularray perhaps is similar in this sense.





^ permalink raw reply	[relevance 5%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-17 11:30  6%       ` Line breaks and brackets in LaTeX export Juan Manuel Macías
  2022-10-17 11:47  9%         ` Ihor Radchenko
@ 2022-10-17 15:01  7%         ` Juan Manuel Macías
  2022-10-17 16:46  5%           ` Max Nikulin
  1 sibling, 1 reply; 200+ results
From: Juan Manuel Macías @ 2022-10-17 15:01 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Daniel Fleischer, Max Nikulin, emacs-orgmode

Juan Manuel Macías writes:

> So, in the current situation, we can ask ourselves: is
> \empty everywhere safe? Everything points to yes. Can we be 100% sure?
> ...?

I think I've found a case where \empty 'everywhere' can produce unexpected
results. I don't know if I'm missing something, because I've never used
this package, but taking a couple of random examples from the tabularray
documentation, you can see it, compiling the following snippet (by the
way, putting \\[0pt] instead of \\\empty the result is correct). Here in
both cases the problem is in the last \empty:

\documentclass{article}
\usepackage{tabularray}

\begin{document}

\section{Normal}

\begin{tblr}{lccr}
\hline
Alpha & Beta & Gamma & Delta \\
\hline
Epsilon & Zeta & Eta & Theta \\
\hline
Iota & Kappa & Lambda & Mu\\
\hline
\end{tblr}

\section{With `empty'}

\begin{tblr}{lccr}
\hline
Alpha & Beta & Gamma & Delta \\\empty
\hline
Epsilon & Zeta & Eta & Theta \\\empty
\hline
Iota & Kappa & Lambda & Mu\\\empty
\hline
\end{tblr}

\section{Normal}

\begin{tblr}[m]{hlines}
Alpha & Beta & Gamma \\
Epsilon & Zeta & Eta\\
Iota & Kappa & Lambda\\
\end{tblr}

\section{With `empty'}

\begin{tblr}[m]{hlines}
Alpha & Beta & Gamma \\\empty
Epsilon & Zeta & Eta\\\empty
Iota & Kappa & Lambda \\\empty
\end{tblr}


^ permalink raw reply	[relevance 7%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-17 11:47  9%         ` Ihor Radchenko
@ 2022-10-17 12:27 10%           ` Juan Manuel Macías
  0 siblings, 0 replies; 200+ results
From: Juan Manuel Macías @ 2022-10-17 12:27 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Daniel Fleischer, Max Nikulin, emacs-orgmode

Ihor Radchenko writes:

> I haven't seen any publication rule that prevents using valid LaTeX
> commands like this. Do you have concrete examples? If not, one could
> argue that any auto-generated output could break some imaginary rule.

No, I don't have any concrete example. But it is one thing to use a
valid LaTeX command and another to use it unnecessarily. It's like
putting \vspace{0pt} between each paragraph.

> I am also wondering how LaTeX documents generated from LyX or TeXmacs
> look like. Are they not using some obvious machine-generated constructs?

I don't know, because I haven't seen them. But I'd bet (at the risk of
losing the bet) that none of those machine-generated constructs produce
anything as unnecessary as Org's present solution. The situation now
becomes the following:

Pandoc: selective solution. In specific cases it returns {[}...{]}

Org: non-selective solution = ugly LaTeX code.

>> Anyway. As for the compilation, it is highly unlikely that \empty will
>> cause any unexpected error. But LaTeX and its over 6000 packages is
>> unpredictable. It also seemed unlikely that \relax would cause any
>> problems, and catching up on the last discussion, it had to be replaced
>> by \empty because it returned an error just before \hline. \relax is one
>> of the recommended solutions from LaTeX, because it tells LaTeX that the
>> previous macro has finished expanding, but it is recommended keeping in
>> mind that the user will apply it only when needed, not everywhere. And
>> before \hline it doesn't make sense because there will never be an
>> '\\[...]' error. So, in the current situation, we can ask ourselves: is
>> \empty everywhere safe? Everything points to yes. Can we be 100% sure?
>> ...?
>
> My answer is: "\\" is 100% not universally safe. Simply because we have
> that bug report with [ ... ] items in tables.
> So, anything with no concrete counter-example is better as long as we
> are reasonably sure that we are not breaking LaTeX conventions.

As I said, this is a known LaTeX problem that occurs in a rare case, for
which there is a known solution (or several), which should be applied in
the specific case. And Org already provides the necessary tools to apply
it.

>> The only thing I can think of, for a non-selective solution like the
>> current one, is the following: if \\ has an optional argument that must
>> be a length, then let's give it, but with a value of zero: \\[0pt], which
>> is equivalent to putting the value by default (zero) explicitly.
>
> This has been proposed and then rejected by Max in
> https://list.orgmode.org/orgmode/ti5tdb$rd2$1@ciao.gmane.io/ and he
> concluded that some side effects are present when using \\[0pt]:
>
> Max>       \\[0pt]
> Max> 
> Max> causes insertion of some code for negative vertical skip (of zero height 
> Max> this case). It should not be really harmful, but I would avoid this

I would like to see some concrete example where this solution was
problematic. \\[0pt] is exactly the same as \\ (as for the effects).
Redundant but valid.



^ permalink raw reply	[relevance 10%]

* Re: Line breaks and brackets in LaTeX export
  2022-10-17 11:30  6%       ` Line breaks and brackets in LaTeX export Juan Manuel Macías
@ 2022-10-17 11:47  9%         ` Ihor Radchenko
  2022-10-17 12:27 10%           ` Juan Manuel Macías
  2022-10-17 15:01  7%         ` Juan Manuel Macías
  1 sibling, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-10-17 11:47 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: Daniel Fleischer, Max Nikulin, emacs-orgmode

Juan Manuel Macías <maciaschain@posteo.net> writes:

> Ihor Radchenko writes:
>
>> I see no issue with defcustom in general, but can you explain what
>> practical problems it is going to solve? I am not talking about
>> aesthetics of the exported LaTeX.
>
> In my opinion it is not so much a question of aesthetics as of (let's
> say) a certain conformity with what a LaTeX document should be. I think,
> for example, in the case of a user who must submit his/her work in LaTeX
> format to a publication, following the rules of that publication. It is
> one thing for a LaTeX document to compile without error and quite
> another for a LaTeX document to be or not to be formed according to good
> practice. Would there be a problem sharing LaTeX documents with
> unnecessary commands like \empty after all occurrences of \\?

I haven't seen any publication rule that prevents using valid LaTeX
commands like this. Do you have concrete examples? If not, one could
argue that any auto-generated output could break some imaginary rule.

I am also wondering how LaTeX documents generated from LyX or TeXmacs
look like. Are they not using some obvious machine-generated constructs?

> Anyway. As for the compilation, it is highly unlikely that \empty will
> cause any unexpected error. But LaTeX and its over 6000 packages is
> unpredictable. It also seemed unlikely that \relax would cause any
> problems, and catching up on the last discussion, it had to be replaced
> by \empty because it returned an error just before \hline. \relax is one
> of the recommended solutions from LaTeX, because it tells LaTeX that the
> previous macro has finished expanding, but it is recommended keeping in
> mind that the user will apply it only when needed, not everywhere. And
> before \hline it doesn't make sense because there will never be an
> '\\[...]' error. So, in the current situation, we can ask ourselves: is
> \empty everywhere safe? Everything points to yes. Can we be 100% sure?
> ...?

My answer is: "\\" is 100% not universally safe. Simply because we have
that bug report with [ ... ] items in tables.
So, anything with no concrete counter-example is better as long as we
are reasonably sure that we are not breaking LaTeX conventions.

> The only thing I can think of, for a non-selective solution like the
> current one, is the following: if \\ has an optional argument that must
> be a length, then let's give it, but with a value of zero: \\[0pt], which
> is equivalent to putting the value by default (zero) explicitly.

This has been proposed and then rejected by Max in
https://list.orgmode.org/orgmode/ti5tdb$rd2$1@ciao.gmane.io/ and he
concluded that some side effects are present when using \\[0pt]:

Max>       \\[0pt]
Max> 
Max> causes insertion of some code for negative vertical skip (of zero height 
Max> this case). It should not be really harmful, but I would avoid this hack.

> What I've done in this code is redefine \\ so that if the next character
> is a [ or a * it doesn't do anything. To use the macro with the old
> behavior, you would have to use the new macros \oldbreak and \oldbreakt
> (this one for tables):
>
> @@latex:\oldbreak@@
> @@latex:[1em]@@

It means that LaTeX packages that redefine \\ may be affected. I'd
prefer to avoid such side effects.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 9%]

* Re: Line breaks and brackets in LaTeX export
  @ 2022-10-17 11:30  6%       ` Juan Manuel Macías
  2022-10-17 11:47  9%         ` Ihor Radchenko
  2022-10-17 15:01  7%         ` Juan Manuel Macías
  0 siblings, 2 replies; 200+ results
From: Juan Manuel Macías @ 2022-10-17 11:30 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Daniel Fleischer, Max Nikulin, emacs-orgmode

Ihor Radchenko writes:

> I see no issue with defcustom in general, but can you explain what
> practical problems it is going to solve? I am not talking about
> aesthetics of the exported LaTeX.

In my opinion it is not so much a question of aesthetics as of (let's
say) a certain conformity with what a LaTeX document should be. I think,
for example, in the case of a user who must submit his/her work in LaTeX
format to a publication, following the rules of that publication. It is
one thing for a LaTeX document to compile without error and quite
another for a LaTeX document to be or not to be formed according to good
practice. Would there be a problem sharing LaTeX documents with
unnecessary commands like \empty after all occurrences of \\?

Anyway. As for the compilation, it is highly unlikely that \empty will
cause any unexpected error. But LaTeX and its over 6000 packages is
unpredictable. It also seemed unlikely that \relax would cause any
problems, and catching up on the last discussion, it had to be replaced
by \empty because it returned an error just before \hline. \relax is one
of the recommended solutions from LaTeX, because it tells LaTeX that the
previous macro has finished expanding, but it is recommended keeping in
mind that the user will apply it only when needed, not everywhere. And
before \hline it doesn't make sense because there will never be an
'\\[...]' error. So, in the current situation, we can ask ourselves: is
\empty everywhere safe? Everything points to yes. Can we be 100% sure?
...?

The only thing I can think of, for a non-selective solution like the
current one, is the following: if \\ has an optional argument that must
be a length, then let's give it, but with a value of zero: \\[0pt], which
is equivalent to putting the value by default (zero) explicitly.

>> This is an example I came up with of how it could be fixed selectively
>> in LaTeX (big, big caveat: it's just a proof of concept and likely to
>> produce errors in other contexts. I think if a LaTeX package to fix this
>> isn't already out, it is either because the problem is very rare and the
>> solution for particular cases is known, or because there are drawbacks
>> inherent to LaTeX that I can't figure out right now):
>>
>> \makeatletter
>>
>> \def\my@protectlbrack{
>>   \@ifnextchar{[}{\relax}{}
>>   \@ifnextchar{*}{\relax}{}
>> }
>>
>> \let\old@break\\
>> \def\\{%
>>   \old@break\my@protectlbrack}
>>
>> %% for tables
>>
>> \let\old@tabularcr\@tabularcr
>> \def\@tabularcr{%
>>   \old@tabularcr\my@protectlbrack}
>>
>> % for use the old commands
>>
>> \newcommand\oldbreak{\old@break}
>> \newcommand\oldbreakt{\old@tabularcr}
>>
>> \makeatother
>>
>> \begin{document}
>>
>> lorem\\
>> [ipsum]
>>
>> lorem\\
>> *ipsum
>>
>> \begin{tabular}{cccc}
>> a & a & a & a \\
>> [a] & a & a & a \\
>> *a & a & a & a \\
>> \end{tabular}
>>
>>
>> \end{document}
>
> Won't it make it impossible to use
> @@latex:\\@@
> @@latex:[1em]@@
>
> deliberately?

What I've done in this code is redefine \\ so that if the next character
is a [ or a * it doesn't do anything. To use the macro with the old
behavior, you would have to use the new macros \oldbreak and \oldbreakt
(this one for tables):

@@latex:\oldbreak@@
@@latex:[1em]@@

Anyway, like I said, it's a proof of concept. In the tests I've done it
works very well, but on a large scale I can't be sure of the results.

Best regards,

Juan Manuel 


^ permalink raw reply	[relevance 6%]

* Re: Export of this table fails LuaLaTeX compilation
  2022-10-12 16:21  0%           ` Max Nikulin
@ 2022-10-13  5:03  0%             ` gerard.vermeulen
  0 siblings, 0 replies; 200+ results
From: gerard.vermeulen @ 2022-10-13  5:03 UTC (permalink / raw)
  To: emacs-orgmode, Emacs-orgmode



On 12.10.2022 18:21, Max Nikulin wrote:
[...]
>>> Stewart Thomas. [BUG] Tables with square brackets do not compile in
>>> PDF (latex) export. Wed, 10 Nov 2021 11:16:10 -0500.
>>> https://list.orgmode.org/CAO12V+wB18nAN0FuDPAeN94GHdt_2nbdJtc4u7n4W3HAZbaZsA@mail.gmail.com
>>> 
>>> I can not figure out an easy way to separate \\ from [b] text but to
>>> prevent the problem you have discovered. I am unsure if
>>> 
>>>     \\[0pt]
>>> 
>>> has no negative consequences and safe enough. I expect that LaTeX
>>> sources are not easy to read when fragile sequences of tokens are
>>> involved.
>>> 
>>> I just have realized that some users might take advantage of earlier
>>> behavior as a feature:
>>> 
>>> - item \\
>>>   [1cm]
>>> - item
>>> 
>>> I think that [1cm] should be treated as text, however I have no idea
>>> how to allow users to specify amount of vertical space and to not
>>> limit line break to LaTeX only. @@latex:\\[1cm]@@ is not suitable 
>>> when
>>> the same text should be exported to ascii, html, etc.
[...]
> Adding \relax is my fault, I did not expect that it may break \hline.
> Such behavior should be stable over decades. The question is how to
> allow users to have square brackets in the beginning of the line
> following \\ and not break some use case.
> 
>> 2. On my systems ws-butler removes the trailing whitespace.
>> 3. I edited your example with nano to add the trailing space after 
>> \relax, but it still does not compile.
> 
> Sorry, I did not get your point with trailing space. LaTeX ignores
> spaces after commands (e.g. "a\relax b" becomes "ab") and in the
> beginning of the line. What I am afraid of is unintentionally
> introduce white space at the beginning of the line, e.g. if
> | a |
> | b |
> |---|
> is exported as
> {} a \\
> {} b \\
> \hline
> then cell contents will be " a" and " b", not "a" and "b".
> \relax a \\
> \relax b \\
> \hline
> has no such problem.

Sorry, I have misread or misunderstood what \relax does with spaces.
Thank you for your patient explanation -- Gerard


^ permalink raw reply	[relevance 0%]

* Re: Export of this table fails LuaLaTeX compilation
  2022-10-12  8:20  7%           ` Max Nikulin
@ 2022-10-13  2:44  0%             ` Ihor Radchenko
  0 siblings, 0 replies; 200+ results
From: Ihor Radchenko @ 2022-10-13  2:44 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

> On 12/10/2022 14:26, Ihor Radchenko wrote:
>> Max Nikulin writes:
>>>
>>> I can not figure out an easy way to separate \\ from [b] text but to
>>> prevent the problem you have discovered. I am unsure if
>>>
>>>       \\[0pt]
>>>
>>> has no negative consequences and safe enough. I expect that LaTeX
>>> sources are not easy to read when fragile sequences of tokens are involved.
>> 
>> What about adding \relax in front of table rows instead of at the end?
>> The hlines are transcoded separately.
>> 
>> All other instances of \\\relax may remain.
>
> If you see a way to implement it, you may try. Do not forget a space 
> after it. Spaces at the beginning of line are insignificant, so 
> insertion of \relax should not cause more ignored spaces than it was 
> before. I would consider skipping "\relax " in the beginning of rows 
> where first cell starts from an export snippet.
>
> I am considering \noalign{} instead of \relax. I was never aware of its 
> effect, but accordingly to The TeXbook it should keep TeX in vertical 
> mode without any action due to empty argument. (Actually I surprised 
> that \relax causes any change of internal state besides parser.) 

If \noalign has less side effects compared to \relax, I'd prefer
\noalign. Can you confirm this?

I was also surprised that \relax does anything except escaping.

> Unfortunately \noalign{} just as \relax will not allow @@latex:[1cm]@@ 
> on the next line, perhaps @@latex:\noalign{\vskip 1cm}@@ is a workaround 
> to introduce additional vertical space.
>
>      \\[0pt]

What you are talking about appears to be abusing our exporter. We give
no guarantees about how \\ is going to be exported internally into
LaTeX. We should have no obligation to keep use-cases like this.

> causes insertion of some code for negative vertical skip (of zero height 
> this case). It should not be really harmful, but I would avoid this hack.
>
> I never used \\* or \\*[10pt] variants of the command. Current stable 
> release should has problems when the line next to \\ starts from * that 
> is not bold marker, besides square brackets.

I feel like I am missing what you are talking about here.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 0%]

* Re: Export of this table fails LuaLaTeX compilation
  2022-10-12  9:17  0%         ` gerard.vermeulen
@ 2022-10-12 16:21  0%           ` Max Nikulin
  2022-10-13  5:03  0%             ` gerard.vermeulen
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2022-10-12 16:21 UTC (permalink / raw)
  To: emacs-orgmode

On 12/10/2022 16:17, gerard.vermeulen@posteo.net wrote:
> 
> 
> On 12.10.2022 07:55, Max Nikulin wrote:
>> On 12/10/2022 12:15, gerard.vermeulen wrote:
>>> On 12.10.2022 06:45, Max Nikulin wrote:
>>>>
>>>> LuaLaTeX is irrelevant. It seems \hline is allowed only immediately
>>>> after \\. Minimal LaTeX example:
>>>>
>>>> \begin{tabular}{l}
>>>> b\\\relax
>>>> \hline
>>>> \end{tabular}
>>>
>>> Your example fails on my Mac texlive-2020 with:
>>>
>>> ! Misplaced \noalign.
>>> \hline ->\noalign
>>>                    {\ifnum 0=`}\fi \hrule \@height \arrayrulewidth 
>>> \futurelet...
>>>
>>> l.40 \hline
>>>
>>> It compiles when I remove \hline
>>
>> Gerard, we forgot to post the reason why \relax has been added after
>> \\. The intention was to  prevent errors in the case of
>>
>> | a   |
>> | [b] |
>>
>> or
>>
>> - item \\
>>   [2022-10-12]
>>
>> Stewart Thomas. [BUG] Tables with square brackets do not compile in
>> PDF (latex) export. Wed, 10 Nov 2021 11:16:10 -0500.
>> https://list.orgmode.org/CAO12V+wB18nAN0FuDPAeN94GHdt_2nbdJtc4u7n4W3HAZbaZsA@mail.gmail.com
>>
>> I can not figure out an easy way to separate \\ from [b] text but to
>> prevent the problem you have discovered. I am unsure if
>>
>>     \\[0pt]
>>
>> has no negative consequences and safe enough. I expect that LaTeX
>> sources are not easy to read when fragile sequences of tokens are
>> involved.
>>
>> I just have realized that some users might take advantage of earlier
>> behavior as a feature:
>>
>> - item \\
>>   [1cm]
>> - item
>>
>> I think that [1cm] should be treated as text, however I have no idea
>> how to allow users to specify amount of vertical space and to not
>> limit line break to LaTeX only. @@latex:\\[1cm]@@ is not suitable when
>> the same text should be exported to ascii, html, etc.
> 
> Max, thanks for the background information.
> 
> For your info:
> 1. I also need to remove \relax in the LaTeX export using Gentoo 
> texlive-2022 to compile.

Adding \relax is my fault, I did not expect that it may break \hline. 
Such behavior should be stable over decades. The question is how to 
allow users to have square brackets in the beginning of the line 
following \\ and not break some use case.

> 2. On my systems ws-butler removes the trailing whitespace.
> 3. I edited your example with nano to add the trailing space after 
> \relax, but it still does not compile.

Sorry, I did not get your point with trailing space. LaTeX ignores 
spaces after commands (e.g. "a\relax b" becomes "ab") and in the 
beginning of the line. What I am afraid of is unintentionally introduce 
white space at the beginning of the line, e.g. if
| a |
| b |
|---|
is exported as
{} a \\
{} b \\
\hline
then cell contents will be " a" and " b", not "a" and "b".
\relax a \\
\relax b \\
\hline
has no such problem.





^ permalink raw reply	[relevance 0%]

* Re: Export of this table fails LuaLaTeX compilation
  2022-10-12  5:55  7%       ` Max Nikulin
  2022-10-12  7:26  0%         ` Ihor Radchenko
@ 2022-10-12  9:17  0%         ` gerard.vermeulen
  2022-10-12 16:21  0%           ` Max Nikulin
  1 sibling, 1 reply; 200+ results
From: gerard.vermeulen @ 2022-10-12  9:17 UTC (permalink / raw)
  To: emacs-orgmode, Emacs-orgmode



On 12.10.2022 07:55, Max Nikulin wrote:
> On 12/10/2022 12:15, gerard.vermeulen wrote:
>> On 12.10.2022 06:45, Max Nikulin wrote:
>>> 
>>> LuaLaTeX is irrelevant. It seems \hline is allowed only immediately
>>> after \\. Minimal LaTeX example:
>>> 
>>> \begin{tabular}{l}
>>> b\\\relax
>>> \hline
>>> \end{tabular}
>> 
>> Your example fails on my Mac texlive-2020 with:
>> 
>> ! Misplaced \noalign.
>> \hline ->\noalign
>>                    {\ifnum 0=`}\fi \hrule \@height \arrayrulewidth 
>> \futurelet...
>> 
>> l.40 \hline
>> 
>> It compiles when I remove \hline
> 
> Gerard, we forgot to post the reason why \relax has been added after
> \\. The intention was to  prevent errors in the case of
> 
> | a   |
> | [b] |
> 
> or
> 
> - item \\
>   [2022-10-12]
> 
> Stewart Thomas. [BUG] Tables with square brackets do not compile in
> PDF (latex) export. Wed, 10 Nov 2021 11:16:10 -0500.
> https://list.orgmode.org/CAO12V+wB18nAN0FuDPAeN94GHdt_2nbdJtc4u7n4W3HAZbaZsA@mail.gmail.com
> 
> I can not figure out an easy way to separate \\ from [b] text but to
> prevent the problem you have discovered. I am unsure if
> 
>     \\[0pt]
> 
> has no negative consequences and safe enough. I expect that LaTeX
> sources are not easy to read when fragile sequences of tokens are
> involved.
> 
> I just have realized that some users might take advantage of earlier
> behavior as a feature:
> 
> - item \\
>   [1cm]
> - item
> 
> I think that [1cm] should be treated as text, however I have no idea
> how to allow users to specify amount of vertical space and to not
> limit line break to LaTeX only. @@latex:\\[1cm]@@ is not suitable when
> the same text should be exported to ascii, html, etc.

Max, thanks for the background information.

For your info:
1. I also need to remove \relax in the LaTeX export using Gentoo 
texlive-2022 to compile.
2. On my systems ws-butler removes the trailing whitespace.
3. I edited your example with nano to add the trailing space after 
\relax, but it still does not compile.



^ permalink raw reply	[relevance 0%]

* Re: Export of this table fails LuaLaTeX compilation
  2022-10-12  7:26  0%         ` Ihor Radchenko
@ 2022-10-12  8:20  7%           ` Max Nikulin
  2022-10-13  2:44  0%             ` Ihor Radchenko
  0 siblings, 1 reply; 200+ results
From: Max Nikulin @ 2022-10-12  8:20 UTC (permalink / raw)
  To: emacs-orgmode

On 12/10/2022 14:26, Ihor Radchenko wrote:
> Max Nikulin writes:
>>
>> I can not figure out an easy way to separate \\ from [b] text but to
>> prevent the problem you have discovered. I am unsure if
>>
>>       \\[0pt]
>>
>> has no negative consequences and safe enough. I expect that LaTeX
>> sources are not easy to read when fragile sequences of tokens are involved.
> 
> What about adding \relax in front of table rows instead of at the end?
> The hlines are transcoded separately.
> 
> All other instances of \\\relax may remain.

If you see a way to implement it, you may try. Do not forget a space 
after it. Spaces at the beginning of line are insignificant, so 
insertion of \relax should not cause more ignored spaces than it was 
before. I would consider skipping "\relax " in the beginning of rows 
where first cell starts from an export snippet.

I am considering \noalign{} instead of \relax. I was never aware of its 
effect, but accordingly to The TeXbook it should keep TeX in vertical 
mode without any action due to empty argument. (Actually I surprised 
that \relax causes any change of internal state besides parser.) 
Unfortunately \noalign{} just as \relax will not allow @@latex:[1cm]@@ 
on the next line, perhaps @@latex:\noalign{\vskip 1cm}@@ is a workaround 
to introduce additional vertical space.

     \\[0pt]

causes insertion of some code for negative vertical skip (of zero height 
this case). It should not be really harmful, but I would avoid this hack.

I never used \\* or \\*[10pt] variants of the command. Current stable 
release should has problems when the line next to \\ starts from * that 
is not bold marker, besides square brackets.




^ permalink raw reply	[relevance 7%]

* Re: Export of this table fails LuaLaTeX compilation
  2022-10-12  5:55  7%       ` Max Nikulin
@ 2022-10-12  7:26  0%         ` Ihor Radchenko
  2022-10-12  8:20  7%           ` Max Nikulin
  2022-10-12  9:17  0%         ` gerard.vermeulen
  1 sibling, 1 reply; 200+ results
From: Ihor Radchenko @ 2022-10-12  7:26 UTC (permalink / raw)
  To: Max Nikulin; +Cc: emacs-orgmode

Max Nikulin <manikulin@gmail.com> writes:

> Gerard, we forgot to post the reason why \relax has been added after \\. 
> The intention was to  prevent errors in the case of
>
> | a   |
> | [b] |
>
> or
>
> - item \\
>    [2022-10-12]
>
> Stewart Thomas. [BUG] Tables with square brackets do not compile in PDF 
> (latex) export. Wed, 10 Nov 2021 11:16:10 -0500. 
> https://list.orgmode.org/CAO12V+wB18nAN0FuDPAeN94GHdt_2nbdJtc4u7n4W3HAZbaZsA@mail.gmail.com
>
> I can not figure out an easy way to separate \\ from [b] text but to 
> prevent the problem you have discovered. I am unsure if
>
>      \\[0pt]
>
> has no negative consequences and safe enough. I expect that LaTeX 
> sources are not easy to read when fragile sequences of tokens are involved.

What about adding \relax in front of table rows instead of at the end?
The hlines are transcoded separately.

All other instances of \\\relax may remain.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[relevance 0%]

* Re: Export of this table fails LuaLaTeX compilation
  @ 2022-10-12  5:55  7%       ` Max Nikulin
  2022-10-12  7:26  0%         ` Ihor Radchenko
  2022-10-12  9:17  0%         ` gerard.vermeulen
  0 siblings, 2 replies; 200+ results
From: Max Nikulin @ 2022-10-12  5:55 UTC (permalink / raw)
  To: emacs-orgmode

On 12/10/2022 12:15, gerard.vermeulen wrote:
> On 12.10.2022 06:45, Max Nikulin wrote:
>>
>> LuaLaTeX is irrelevant. It seems \hline is allowed only immediately
>> after \\. Minimal LaTeX example:
>>
>> \begin{tabular}{l}
>> b\\\relax
>> \hline
>> \end{tabular}
> 
> Your example fails on my Mac texlive-2020 with:
> 
> ! Misplaced \noalign.
> \hline ->\noalign
>                    {\ifnum 0=`}\fi \hrule \@height \arrayrulewidth 
> \futurelet...
> 
> l.40 \hline
> 
> It compiles when I remove \hline

Gerard, we forgot to post the reason why \relax has been added after \\. 
The intention was to  prevent errors in the case of

| a   |
| [b] |

or

- item \\
   [2022-10-12]

Stewart Thomas. [BUG] Tables with square brackets do not compile in PDF 
(latex) export. Wed, 10 Nov 2021 11:16:10 -0500. 
https://list.orgmode.org/CAO12V+wB18nAN0FuDPAeN94GHdt_2nbdJtc4u7n4W3HAZbaZsA@mail.gmail.com

I can not figure out an easy way to separate \\ from [b] text but to 
prevent the problem you have discovered. I am unsure if

     \\[0pt]

has no negative consequences and safe enough. I expect that LaTeX 
sources are not easy to read when fragile sequences of tokens are involved.

I just have realized that some users might take advantage of earlier 
behavior as a feature:

- item \\
   [1cm]
- item

I think that [1cm] should be treated as text, however I have no idea how 
to allow users to specify amount of vertical space and to not limit line 
break to LaTeX only. @@latex:\\[1cm]@@ is not suitable when the same 
text should be exported to ascii, html, etc.




^ permalink raw reply	[relevance 7%]

* svg file from tikz picture
       [not found]     <3bc47afb-0bac-f6e8-1097-13dcb6f2be1f@housseini.me>
@ 2022-08-15 18:50  4% ` reza
  0 siblings, 0 replies; 200+ results
From: reza @ 2022-08-15 18:50 UTC (permalink / raw)
  To: emacs-orgmode@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1369 bytes --]

Hi list

when running the following code

#+header: :file "absolute-distance.pdf"
#+header: :results file drawer :exports results :fit yes :border 0cm
#+header: :headers '("\\usepackage{tikz}")
#+begin_src latex
   \usetikzlibrary{positioning}
   \begin{tikzpicture}
     \node[circle,fill,label=above:$P_1$,node font=\Large] (point1) at 
(0,0) {};
     \node[circle,fill,label=above:$P_2$,node font=\Large] (point2) at 
(3,0) {};
     \draw[latex-latex] (point1) -- (point2);
   \end{tikzpicture}
#+end_src

everything runs fine and a pdf file gets produced. But when I change the 
file header to "absolute-distance.svg" an error occurs and no output 
gets produced. Find attached the tex file and the log of the compilation.

What is the problem here, why is it defining "\pgfsysdriver" in the 
preamble of the tex document. I thought it is converting the produced 
pdf file with imagemagick (or inkscape?) to svg?

Thanks for any clarification.

Cheers Reza

P.S:

My workaround consist in producing a pdf file and convert it with a 
":post pdftosvg(file=*this*)" header call to svg. This is the post block

#+name: pdftosvg
#+begin_src shell :var file="" :exports none :results output
   pdf2svg ${file:7:-2} ${file:7:-5}"svg" && echo 
"[[file:"${file:7:-5}"svg]]"
#+end_src

but it feels a little hacky and cumbersome and it would be nice to 
produce directly svg

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: latex-kc4M19.log --]
[-- Type: text/x-log; name=latex-kc4M19.log, Size: 152094 bytes --]

This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2021/GNU Guix) (preloaded format=pdflatex 2022.5.9)  15 AUG 2022 20:36
entering extended mode
 restricted \write18 enabled.
 %&-line parsing enabled.
**/tmp/babel-4i2CC5/latex-kc4M19.tex
(/tmp/babel-4i2CC5/latex-kc4M19.tex
LaTeX2e <2020-10-01> patch level 4
L3 programming layer <2021-02-18>
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/standalone/standalone.cls
Document Class: standalone 2018/03/26 v1.3a Class to compile TeX sub-files stan
dalone

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/tools/shellesc.sty
Package: shellesc 2019/11/08 v1.0c unified shell escape interface for LaTeX
Package shellesc Info: Restricted shell escape enabled on input line 77.
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/iftex/ifluatex.sty
Package: ifluatex 2019/10/25 v1.5 ifluatex legacy package. Use iftex instead.

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/iftex/iftex.sty
Package: iftex 2020/03/06 v1.0d TeX engine tests
))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/xkeyval/xkeyval.sty
Package: xkeyval 2020/11/20 v2.8 package option processing (HA)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/xkeyval/xkeyval.tex
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/xkeyval/xkvutils.tex
\XKV@toks=\toks15
\XKV@tempa@toks=\toks16

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/xkeyval/keyval.tex))
\XKV@depth=\count179
File: xkeyval.tex 2014/12/03 v2.7a key=value parser (HA)
))
\sa@internal=\count180
\c@sapage=\count181

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/standalone/standalone.cfg
File: standalone.cfg 2018/03/26 v1.3a Default configuration file for 'standalon
e' class
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/base/article.cls
Document Class: article 2020/04/10 v1.4m Standard LaTeX document class

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/base/size10.clo
File: size10.clo 2020/04/10 v1.4m Standard LaTeX file (size option)
)
\c@part=\count182
\c@section=\count183
\c@subsection=\count184
\c@subsubsection=\count185
\c@paragraph=\count186
\c@subparagraph=\count187
\c@figure=\count188
\c@table=\count189
\abovecaptionskip=\skip47
\belowcaptionskip=\skip48
\bibindent=\dimen138
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/preview/preview.sty
Package: preview 2017/04/24 12.3 (AUCTeX/preview-latex)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/luatex85/luatex85.sty
Package: luatex85 2016/06/15 v1.4 pdftex aliases for luatex
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/preview/prtightpage.def
\PreviewBorder=\dimen139
)
\pr@snippet=\count190
\pr@box=\box47
\pr@output=\toks17
))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/frontendlayer/tikz.sty
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/basiclayer/pgf.sty
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/utilities/pgfrcs.sty
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/utilities/pgfutil-common.tex
\pgfutil@everybye=\toks18
\pgfutil@tempdima=\dimen140
\pgfutil@tempdimb=\dimen141

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/utilities/pgfutil-latex.def
\pgfutil@abb=\box48
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/utilities/pgfrcs.code.tex
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/pgf.revision.tex)
Package: pgfrcs 2020/12/27 v3.1.8b (3.1.8b)
))
Package: pgf 2020/12/27 v3.1.8b (3.1.8b)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/basiclayer/pgfcore.sty
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/graphics/graphicx.sty
Package: graphicx 2020/09/09 v1.2b Enhanced LaTeX Graphics (DPC,SPQR)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/graphics/graphics.sty
Package: graphics 2020/08/30 v1.4c Standard LaTeX Graphics (DPC,SPQR)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/graphics/trig.sty
Package: trig 2016/01/03 v1.10 sin cos tan (DPC)
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/graphics-cfg/graphics.cfg
File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration
)
Package graphics Info: Driver file: pdftex.def on input line 105.

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/graphics-def/pdftex.def
File: pdftex.def 2020/10/05 v1.2a Graphics/color driver for pdftex
))
\Gin@req@height=\dimen142
\Gin@req@width=\dimen143
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/systemlayer/pgfsys.sty
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex
Package: pgfsys 2020/12/27 v3.1.8b (3.1.8b)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
\pgfkeys@pathtoks=\toks19
\pgfkeys@temptoks=\toks20

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex
\pgfkeys@tmptoks=\toks21
))
\pgf@x=\dimen144
\pgf@y=\dimen145
\pgf@xa=\dimen146
\pgf@ya=\dimen147
\pgf@xb=\dimen148
\pgf@yb=\dimen149
\pgf@xc=\dimen150
\pgf@yc=\dimen151
\pgf@xd=\dimen152
\pgf@yd=\dimen153
\w@pgf@writea=\write3
\r@pgf@reada=\read2
\c@pgf@counta=\count191
\c@pgf@countb=\count192
\c@pgf@countc=\count193
\c@pgf@countd=\count194
\t@pgf@toka=\toks22
\t@pgf@tokb=\toks23
\t@pgf@tokc=\toks24
\pgf@sys@id@count=\count195

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/systemlayer/pgf.cfg
File: pgf.cfg 2020/12/27 v3.1.8b (3.1.8b)
)
Driver file for pgf: pgfsys-tex4ht.def

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def
File: pgfsys-tex4ht.def 2020/12/27 v3.1.8b (3.1.8b)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def
File: pgfsys-common-svg.def 2020/12/27 v3.1.8b (3.1.8b)
\pgf@sys@svg@objectcount=\count196
\pgf@sys@svg@scopecount=\count197
\pgf@sys@svg@type@count=\count198
\pgf@sys@svg@canvascount=\count199
)
\pgf@sys@svg@picnum=\count266
\pgf@sys@svg@nodenum=\count267
\pgfsys@foreignobject@Box=\box49
\pgf@s=\dimen154
\pgf@t=\dimen155

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/xcolor/xcolor.sty
Package: xcolor 2016/05/11 v2.12 LaTeX color extensions (UK)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/graphics-cfg/color.cfg
File: color.cfg 2016/01/02 v1.6 sample color configuration
)
Package xcolor Info: Driver file: pdftex.def on input line 225.
Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1348.
Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1352.
Package xcolor Info: Model `RGB' extended on input line 1364.
Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1366.
Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1367.
Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1368.
Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1369.
Package xcolor Info: Model `Gray' substituted by `gray' on input line 1370.
Package xcolor Info: Model `wave' substituted by `hsb' on input line 1371.
)))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex
File: pgfsyssoftpath.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgfsyssoftpath@smallbuffer@items=\count268
\pgfsyssoftpath@bigbuffer@items=\count269
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/systemlayer/pgfsysprotocol.code.tex
File: pgfsysprotocol.code.tex 2020/12/27 v3.1.8b (3.1.8b)
))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcore.code.tex
Package: pgfcore 2020/12/27 v3.1.8b (3.1.8b)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmath.code.tex
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathcalc.code.tex
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathutil.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathparser.code.tex
\pgfmath@dimen=\dimen156
\pgfmath@count=\count270
\pgfmath@box=\box50
\pgfmath@toks=\toks25
\pgfmath@stack@operand=\toks26
\pgfmath@stack@operation=\toks27
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.random.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.comparison.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.round.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex)))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmathfloat.code.tex
\c@pgfmathroundto@lastzeros=\count271
))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfint.code.tex)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex
File: pgfcorepoints.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgf@picminx=\dimen157
\pgf@picmaxx=\dimen158
\pgf@picminy=\dimen159
\pgf@picmaxy=\dimen160
\pgf@pathminx=\dimen161
\pgf@pathmaxx=\dimen162
\pgf@pathminy=\dimen163
\pgf@pathmaxy=\dimen164
\pgf@xx=\dimen165
\pgf@xy=\dimen166
\pgf@yx=\dimen167
\pgf@yy=\dimen168
\pgf@zx=\dimen169
\pgf@zy=\dimen170
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex
File: pgfcorepathconstruct.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgf@path@lastx=\dimen171
\pgf@path@lasty=\dimen172
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex
File: pgfcorepathusage.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgf@shorten@end@additional=\dimen173
\pgf@shorten@start@additional=\dimen174
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex
File: pgfcorescopes.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgfpic=\box51
\pgf@hbox=\box52
\pgf@layerbox@main=\box53
\pgf@picture@serial@count=\count272
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex
File: pgfcoregraphicstate.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgflinewidth=\dimen175
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex
File: pgfcoretransformations.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgf@pt@x=\dimen176
\pgf@pt@y=\dimen177
\pgf@pt@temp=\dimen178
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorequick.code.tex
File: pgfcorequick.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcoreobjects.code.tex
File: pgfcoreobjects.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex
File: pgfcorepathprocessing.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex
File: pgfcorearrows.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgfarrowsep=\dimen179
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex
File: pgfcoreshade.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgf@max=\dimen180
\pgf@sys@shading@range@num=\count273
\pgf@shadingcount=\count274
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex
File: pgfcoreimage.code.tex 2020/12/27 v3.1.8b (3.1.8b)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex
File: pgfcoreexternal.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgfexternal@startupbox=\box54
))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex
File: pgfcorelayers.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex
File: pgfcoretransparency.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex
File: pgfcorepatterns.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/basiclayer/pgfcorerdf.code.tex
File: pgfcorerdf.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex
File: pgfmoduleshapes.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgfnodeparttextbox=\box55
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex
File: pgfmoduleplot.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/compatibility/pgfcomp-version-0-65.sty
Package: pgfcomp-version-0-65 2020/12/27 v3.1.8b (3.1.8b)
\pgf@nodesepstart=\dimen181
\pgf@nodesepend=\dimen182
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/compatibility/pgfcomp-version-1-18.sty
Package: pgfcomp-version-1-18 2020/12/27 v3.1.8b (3.1.8b)
))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/utilities/pgffor.sty
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/utilities/pgfkeys.sty
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/utilities/pgfkeys.code.tex))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/pgf/math/pgfmath.sty
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmath.code.tex))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/utilities/pgffor.code.tex
Package: pgffor 2020/12/27 v3.1.8b (3.1.8b)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/math/pgfmath.code.tex)
\pgffor@iter=\dimen183
\pgffor@skip=\dimen184
\pgffor@stack=\toks28
\pgffor@toks=\toks29
))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex
Package: tikz 2020/12/27 v3.1.8b (3.1.8b)

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex
File: pgflibraryplothandlers.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgf@plot@mark@count=\count275
\pgfplotmarksize=\dimen185
)
\tikz@lastx=\dimen186
\tikz@lasty=\dimen187
\tikz@lastxsaved=\dimen188
\tikz@lastysaved=\dimen189
\tikz@lastmovetox=\dimen190
\tikz@lastmovetoy=\dimen191
\tikzleveldistance=\dimen192
\tikzsiblingdistance=\dimen193
\tikz@figbox=\box56
\tikz@figbox@bg=\box57
\tikz@tempbox=\box58
\tikz@tempbox@bg=\box59
\tikztreelevel=\count276
\tikznumberofchildren=\count277
\tikznumberofcurrentchild=\count278
\tikz@fig@count=\count279

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex
File: pgfmodulematrix.code.tex 2020/12/27 v3.1.8b (3.1.8b)
\pgfmatrixcurrentrow=\count280
\pgfmatrixcurrentcolumn=\count281
\pgf@matrix@numberofcolumns=\count282
)
\tikz@expandcount=\count283

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarytopaths.code.tex
File: tikzlibrarytopaths.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/l3backend/l3backend-pdftex.def
File: l3backend-pdftex.def 2021-03-18 L3 backend support: PDF output (pdfTeX)
\l__color_backend_stack_int=\count284
\l__pdf_internal_box=\box60
)
(/tmp/babel-4i2CC5/latex-kc4M19.aux)
\openout1 = `latex-kc4M19.aux'.

LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 3.
LaTeX Font Info:    ... okay on input line 3.
LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line 3.
LaTeX Font Info:    ... okay on input line 3.
LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 3.
LaTeX Font Info:    ... okay on input line 3.
LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 3.
LaTeX Font Info:    ... okay on input line 3.
LaTeX Font Info:    Checking defaults for TS1/cmr/m/n on input line 3.
LaTeX Font Info:    ... okay on input line 3.
LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 3.
LaTeX Font Info:    ... okay on input line 3.
LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 3.
LaTeX Font Info:    ... okay on input line 3.

Preview: Fontsize 10pt
Preview: PDFoutput 1

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/context/base/mkii/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
\scratchcounter=\count285
\scratchdimen=\dimen194
\scratchbox=\box61
\nofMPsegments=\count286
\nofMParguments=\count287
\everyMPshowfont=\toks30
\MPscratchCnt=\count288
\MPscratchDim=\dimen195
\MPnumerator=\count289
\makeMPintoPDFobject=\count290
\everyMPtoPDFconversion=\toks31
)
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty
Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf
Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4
85.

(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/latex/latexconfig/epstopdf-sys.cfg
File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
e
))
(/gnu/store/09ivp0wl5l7n9g2v3cwzdpqhzly3m2rh-texlive-texmf-20210325/share/texmf
-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypositioning.code.
tex
File: tikzlibrarypositioning.code.tex 2020/12/27 v3.1.8b (3.1.8b)
)
! Undefined control sequence.
\pgfsys@beginpicture ...ys@svg@boxmodefalse \EndP 
                                                  \HtmlParOff \pgfkeys {/pgf...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@beginpicture ...defalse \EndP \HtmlParOff 
                                                  \pgfkeys {/pgf/tex4ht node...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@mtext@configure ->\Configure 
                                     {$$}{}{}{}\Configure {$}{}{}{}\Configur...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

LaTeX Font Info:    External font `cmex10' loaded for size
(Font)              <7> on input line 5.
LaTeX Font Info:    External font `cmex10' loaded for size
(Font)              <5> on input line 5.
! Undefined control sequence.
\pgfsys@mtext@configure ...e {$$}{}{}{}\Configure 
                                                  {$}{}{}{}\Configure {SUB}{...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Extra }, or forgotten $.
<recently read> }
                 
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
I've deleted a group-closing symbol because it seems to be
spurious, as in `$x}$'. But perhaps the } is legitimate and
you forgot something else, as in `\hbox{$x}'. In such cases
the way to recover is to insert both the forgotten and the
deleted material, e.g., by typing `I$}'.

! Undefined control sequence.
\pgfsys@mtext@configure ...re {$}{}{}{}\Configure 
                                                  {SUB}{\HCode {<tspan basel...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@mtext@configure ...Configure {SUB}{\HCode 
                                                  {<tspan baseline-shift="su...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@mtext@configure ...-shift="sub">}}{\HCode 
                                                  {</tspan>}}\Configure {SUP...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@mtext@configure ... {</tspan>}}\Configure 
                                                  {SUP}{\HCode {<tspan basel...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@mtext@configure ...Configure {SUP}{\HCode 
                                                  {<tspan baseline-shift="su...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@mtext@configure ...-shift="sub">}}{\HCode 
                                                  {</tspan>}}\Configure {SUB...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@mtext@configure ... {</tspan>}}\Configure 
                                                  {SUBSUP}{}{}{}\Configure {...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@mtext@configure ...UBSUP}{}{}{}\Configure 
                                                  {htf} {0}{+}{<tspan font-f...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@beginpicture ...s@CssIncluded@ \else \Css 
                                                  { .foreignobject {line-hei...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@beginpicture ...ext-align:center; } }\Css 
                                                  {math {vertical-align:base...
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5   \node
           [circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0...
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no # in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no p in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no M in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no Z in font nullfont!
Missing character: There is no M in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no # in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...ikz@textcolor }\fi \fi \fi \HCode 
                                                  {<text style="stroke:none"...
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no y in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no : in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no c in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no c in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...@size \pgfutil@empty \else \HCode 
                                                  { font-size="\f@size "}\fi...
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no z in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...nt-size="\f@size "}\fi \fi \HCode 
                                                  {>\Hnewline }\wd #1=0pt\ht...
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...size "}\fi \fi \HCode {>\Hnewline 
                                                  }\wd #1=0pt\ht #1=0pt\dp #...
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@hbox ...ht #1=0pt\dp #1=0pt\box #1 \HCode 
                                                  {</text>\Hnewline }
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...t\box #1 \HCode {</text>\Hnewline 
                                                  }
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no # in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no # in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...ikz@textcolor }\fi \fi \fi \HCode 
                                                  {<text style="stroke:none"...
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no y in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no : in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no c in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no c in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...@size \pgfutil@empty \else \HCode 
                                                  { font-size="\f@size "}\fi...
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no z in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...nt-size="\f@size "}\fi \fi \HCode 
                                                  {>\Hnewline }\wd #1=0pt\ht...
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...size "}\fi \fi \HCode {>\Hnewline 
                                                  }\wd #1=0pt\ht #1=0pt\dp #...
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@hbox ...ht #1=0pt\dp #1=0pt\box #1 \HCode 
                                                  {</text>\Hnewline }
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...t\box #1 \HCode {</text>\Hnewline 
                                                  }
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.5 ..._1$,node font=\Large] (point1) at (0,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no # in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no p in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no M in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no Z in font nullfont!
Missing character: There is no M in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no # in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...ikz@textcolor }\fi \fi \fi \HCode 
                                                  {<text style="stroke:none"...
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no y in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no : in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no c in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no c in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...@size \pgfutil@empty \else \HCode 
                                                  { font-size="\f@size "}\fi...
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no z in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...nt-size="\f@size "}\fi \fi \HCode 
                                                  {>\Hnewline }\wd #1=0pt\ht...
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...size "}\fi \fi \HCode {>\Hnewline 
                                                  }\wd #1=0pt\ht #1=0pt\dp #...
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@hbox ...ht #1=0pt\dp #1=0pt\box #1 \HCode 
                                                  {</text>\Hnewline }
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...t\box #1 \HCode {</text>\Hnewline 
                                                  }
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no # in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no # in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...ikz@textcolor }\fi \fi \fi \HCode 
                                                  {<text style="stroke:none"...
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no y in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no : in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no c in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no c in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...@size \pgfutil@empty \else \HCode 
                                                  { font-size="\f@size "}\fi...
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no z in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...nt-size="\f@size "}\fi \fi \HCode 
                                                  {>\Hnewline }\wd #1=0pt\ht...
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...size "}\fi \fi \HCode {>\Hnewline 
                                                  }\wd #1=0pt\ht #1=0pt\dp #...
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@hbox ...ht #1=0pt\dp #1=0pt\box #1 \HCode 
                                                  {</text>\Hnewline }
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no > in font nullfont!
! Undefined control sequence.
\pgfsys@hbox ...t\box #1 \HCode {</text>\Hnewline 
                                                  }
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.6 ..._2$,node font=\Large] (point2) at (3,0) {};
                                                  
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no p in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no M in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no L in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no " in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no i in font nullfont!
Missing character: There is no x in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 6 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no p in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no M in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no L in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no f in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no m in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no l in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no ( in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no , in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no ) in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no p in font nullfont!
Missing character: There is no a in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no h in font nullfont!
Missing character: There is no d in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no M in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no L in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 1 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 4 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no C in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 7 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 8 in font nullfont!
Missing character: There is no - in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 2 in font nullfont!
Missing character: There is no 3 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 9 in font nullfont!
Missing character: There is no 5 in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no . in font nullfont!
Missing character: There is no 0 in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no s in font nullfont!
Missing character: There is no t in font nullfont!
Missing character: There is no r in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no k in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no = in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no o in font nullfont!
Missing character: There is no n in font nullfont!
Missing character: There is no e in font nullfont!
Missing character: There is no " in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.7   \draw[latex-latex] (point1) -- (point2);
                                              
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Missing character: There is no < in font nullfont!
Missing character: There is no / in font nullfont!
Missing character: There is no g in font nullfont!
Missing character: There is no > in font nullfont!
Missing character: There is no 
 in font nullfont!
! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@endpicture ->\HtmlParOn 
                                \par 
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Missing $ inserted.
<inserted text> 
                $
l.8 \end{tikzpicture}
                     \end{document}
I've inserted a begin-math/end-math symbol since I think
you left one out. Proceed, with fingers crossed.

! Missing } inserted.
<inserted text> 
                }
l.8 \end{tikzpicture}
                     \end{document}
I've inserted something that you may have forgotten.
(See the <inserted text> above.)
With luck, this will get me unwedged. But if you
really didn't forget anything, try typing `2' now; then
my insertion and my current dilemma will both disappear.

! Undefined control sequence.
\pgfsys@typesetpicturebox ...rrentprotocol \HCode 
                                                  {<object data="\jobname -\...
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
<argument> ...-8859-1" standalone="no"?>\Hnewline 
                                                  <?xml-stylesheet href="\pg...
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
<argument> ...ss .css" type="text/css"?>\Hnewline 
                                                  
l.8 \end{tikzpicture}
                     \end{document}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\pgfsys@invoke #1->\HCode 
                          {#1}
l.8 \end{tikzpicture}
                     \end{document}
(That makes 100 errors; please try again.) 
Here is how much of TeX's memory you used:
 12489 strings out of 478994
 268508 string characters out of 5833535
 523022 words of memory out of 5000000
 29767 multiletter control sequences out of 15000+600000
 403728 words of font info for 28 fonts, out of 8000000 for 9000
 1141 hyphenation exceptions out of 8191
 113i,6n,116p,489b,780s stack positions out of 5000i,500n,10000p,200000b,80000s

!  ==> Fatal error occurred, no output PDF file produced!

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: latex-kc4M19.tex --]
[-- Type: text/x-tex; name=latex-kc4M19.tex, Size: 385 bytes --]

\documentclass[preview]{standalone}
\def\pgfsysdriver{pgfsys-tex4ht.def}
\usepackage{tikz}\begin{document}\usetikzlibrary{positioning}
\begin{tikzpicture}
  \node[circle,fill,label=above:$P_1$,node font=\Large] (point1) at (0,0) {};
  \node[circle,fill,label=above:$P_2$,node font=\Large] (point2) at (3,0) {};
  \draw[latex-latex] (point1) -- (point2);
\end{tikzpicture}\end{document}

[-- Attachment #4: OpenPGP_0xC375C6AF05125C52.asc --]
[-- Type: application/pgp-keys, Size: 15557 bytes --]

[-- Attachment #5: OpenPGP_signature --]
[-- Type: application/pgp-signature, Size: 499 bytes --]

^ permalink raw reply	[relevance 4%]

* Re: [PATCH] (v3) New LaTeX code export option: engraved
  2022-05-08 14:30  2%               ` [PATCH] (v2) " Timothy
@ 2022-05-11 16:05  2%                 ` Timothy
  0 siblings, 0 replies; 200+ results
From: Timothy @ 2022-05-11 16:05 UTC (permalink / raw)
  To: Daniel Fleischer; +Cc: Ihor Radchenko, emacs-orgmode, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 799 bytes --]

Hi All,

I now have what I hope is the final set of patches[1].

Compared to v2 we have:
• a fix for % in captions (long standing bug)
• support for mathescaped code
• a news/manual entry for engraved
• a collection of tweaks based on Ihor’s lovely feedback 🤗

I’ve also slipped in a patch to `org-latex--label' which adds the `lst:' prefix
(short for listings) to `\label's generated for source blocks. This seemed like a
decent idea while I was working on captions, if anyone thinks otherwise I’ll
happily leave it out.

Daniel, if you’re happy with these commits let me know and I’ll push them :)

All the best,
Timothy



Footnotes
─────────

[1] For getting this feature
into Org. I’m sure there will be tweaks in the future.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Refactor-org-latex-src-block.patch --]
[-- Type: text/x-patch, Size: 15944 bytes --]

From 18adbd0e1226cf3307090861e09e92bfa9cdfbf1 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 14:35:34 +0800
Subject: [PATCH 01/13] ox-latex: Refactor `org-latex-src-block'

* lisp/ox-latex.el (org-latex-src-block): Extract the per-format logic
from `org-latex-src-block' into new dedicated functions:
+ `org-latex-src-block--verbatim'
+ `org-latex-src-block--custom'
+ `org-latex-src-block--minted'
+ `org-latex-src-block--listings'
This makes `org-latex-src-block' much less monolithic, taking it from
175 lines to 30, and I find also makes it easier to understand.
---
 lisp/ox-latex.el | 339 ++++++++++++++++++++++++++---------------------
 1 file changed, 185 insertions(+), 154 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 841ad48bc..c2f728a1c 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2997,164 +2997,195 @@ (defun org-latex-src-block (src-block _contents info)
 	   (float (plist-get attributes :float))
 	   (listings (plist-get info :latex-listings)))
       (cond
-       ;; Case 1.  No source fontification.
        ((or (not lang) (not listings))
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
-                                (org-export-format-code-default src-block info))))
-          (cond ((string= "multicolumn" float)
-                 (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
-                         (plist-get info :latex-default-figure-position)
-                         (if caption-above-p caption-str "")
-                         verbatim
-                         (if caption-above-p "" caption-str)))
-                (caption (concat
-                          (if caption-above-p caption-str "")
-                          verbatim
-                          (if caption-above-p "" (concat "\n" caption-str))))
-                (t verbatim))))
-       ;; Case 2.  Custom environment.
+        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (custom-env
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (formatted-src (org-export-format-code-default src-block info)))
-          (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
-	      (format "\\begin{%s}\n%s\\end{%s}\n"
-		      custom-env
-		      (concat (and caption-above-p caption-str)
-			      formatted-src
-			      (and (not caption-above-p) caption-str))
-		      custom-env)
-	    (format-spec custom-env
-			 `((?s . ,formatted-src)
-			   (?c . ,caption)
-			   (?f . ,float)
-			   (?l . ,(org-latex--label src-block info))
-			   (?o . ,(or (plist-get attributes :options) "")))))))
-       ;; Case 3.  Use minted package.
+        (org-latex-src-block--custom src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
-	(let* ((caption-str (org-latex--caption/label-string src-block info))
-	       (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
-			      (plist-get info :latex-default-figure-position)))
-	       (float-env
-		(cond
-		 ((string= "multicolumn" float)
-		  (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 (caption
-		  (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 ((string= "t" float)
-		  (concat (format "\\begin{listing}[%s]\n"
-				  placement)
-			  "%s\n\\end{listing}"))
-		 (t "%s")))
-	       (options (plist-get info :latex-minted-options))
-	       (body
-		(format
-		 "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
-		 ;; Options.
-		 (concat
-		  (org-latex--make-option-string
-		   (if (or (not num-start) (assoc "linenos" options))
-		       options
-		     (append
-		      `(("linenos")
-			("firstnumber" ,(number-to-string (1+ num-start))))
-		      options)))
-		  (let ((local-options (plist-get attributes :options)))
-		    (and local-options (concat "," local-options))))
-		 ;; Language.
-		 (or (cadr (assq (intern lang)
-				 (plist-get info :latex-minted-langs)))
-		     (downcase lang))
-		 ;; Source code.
-		 (let* ((code-info (org-export-unravel-code src-block))
-			(max-width
-			 (apply 'max
-				(mapcar 'length
-					(org-split-string (car code-info)
-							  "\n")))))
-		   (org-export-format-code
-		    (car code-info)
-		    (lambda (loc _num ref)
-		      (concat
-		       loc
-		       (when ref
-			 ;; Ensure references are flushed to the right,
-			 ;; separated with 6 spaces from the widest line
-			 ;; of code.
-			 (concat (make-string (+ (- max-width (length loc)) 6)
-					      ?\s)
-				 (format "(%s)" ref)))))
-		    nil (and retain-labels (cdr code-info)))))))
-	  ;; Return value.
-	  (format float-env body)))
-       ;; Case 4.  Use listings package.
+        (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (t
-	(let ((lst-lang
-	       (or (cadr (assq (intern lang)
-			       (plist-get info :latex-listings-langs)))
-		   lang))
-	      (caption-str
-	       (when caption
-		 (let ((main (org-export-get-caption src-block))
-		       (secondary (org-export-get-caption src-block t)))
-		   (if (not secondary)
-		       (format "{%s}" (org-export-data main info))
-		     (format "{[%s]%s}"
-			     (org-export-data secondary info)
-			     (org-export-data main info))))))
-	      (lst-opt (plist-get info :latex-listings-options)))
-	  (concat
-	   ;; Options.
-	   (format
-	    "\\lstset{%s}\n"
-	    (concat
-	     (org-latex--make-option-string
-	      (append
-	       lst-opt
-	       (cond
-		((and (not float) (plist-member attributes :float)) nil)
-		((string= "multicolumn" float) '(("float" "*")))
-		((and float (not (assoc "float" lst-opt)))
-		 `(("float" ,(plist-get info :latex-default-figure-position)))))
-	       `(("language" ,lst-lang))
-	       (if label
-		   `(("label" ,(org-latex--label src-block info)))
-		 '(("label" " ")))
-	       (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
-	       `(("captionpos" ,(if caption-above-p "t" "b")))
-	       (cond ((assoc "numbers" lst-opt) nil)
-		     ((not num-start) '(("numbers" "none")))
-		     (t `(("firstnumber" ,(number-to-string (1+ num-start)))
-			  ("numbers" "left"))))))
-	     (let ((local-options (plist-get attributes :options)))
-	       (and local-options (concat "," local-options)))))
-	   ;; Source code.
-	   (format
-	    "\\begin{lstlisting}\n%s\\end{lstlisting}"
-	    (let* ((code-info (org-export-unravel-code src-block))
-		   (max-width
-		    (apply 'max
-			   (mapcar 'length
-				   (org-split-string (car code-info) "\n")))))
-	      (org-export-format-code
-	       (car code-info)
-	       (lambda (loc _num ref)
-		 (concat
-		  loc
-		  (when ref
-		    ;; Ensure references are flushed to the right,
-		    ;; separated with 6 spaces from the widest line of
-		    ;; code
-		    (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
-			    (format "(%s)" ref)))))
-	       nil (and retain-labels (cdr code-info))))))))))))
-
+        (org-latex-src-block--listings src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))))))
+
+(defun org-latex-src-block--verbatim
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels _attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
+                          (org-export-format-code-default src-block info))))
+    (cond ((string= "multicolumn" float)
+           (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
+                   (plist-get info :latex-default-figure-position)
+                   (if caption-above-p caption-str "")
+                   verbatim
+                   (if caption-above-p "" caption-str)))
+          (caption (concat
+                    (if caption-above-p caption-str "")
+                    verbatim
+                    (if caption-above-p "" (concat "\n" caption-str))))
+          (t verbatim))))
+
+(defun org-latex-src-block--custom
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels attributes float custom-env)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (formatted-src (org-export-format-code-default src-block info)))
+    (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
+        (format "\\begin{%s}\n%s\\end{%s}\n"
+                custom-env
+                (concat (and caption-above-p caption-str)
+                        formatted-src
+                        (and (not caption-above-p) caption-str))
+                custom-env)
+      (format-spec custom-env
+                   `((?s . ,formatted-src)
+                     (?c . ,caption)
+                     (?f . ,float)
+                     (?l . ,(org-latex--label src-block info))
+                     (?o . ,(or (plist-get attributes :options) "")))))))
+
+(defun org-latex-src-block--minted
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-minted-options))
+         (body
+          (format
+           "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (if (or (not num-start) (assoc "linenos" options))
+                 options
+               (append
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start))))
+                options)))
+            (let ((local-options (plist-get attributes :options)))
+              (and local-options (concat "," local-options))))
+           ;; Language.
+           (or (cadr (assq (intern lang)
+                           (plist-get info :latex-minted-langs)))
+               (downcase lang))
+           ;; Source code.
+           (let* ((code-info (org-export-unravel-code src-block))
+                  (max-width
+                   (apply 'max
+                          (mapcar 'length
+                                  (org-split-string (car code-info)
+                                                    "\n")))))
+             (org-export-format-code
+              (car code-info)
+              (lambda (loc _num ref)
+                (concat
+                 loc
+                 (when ref
+                   ;; Ensure references are flushed to the right,
+                   ;; separated with 6 spaces from the widest line
+                   ;; of code.
+                   (concat (make-string (+ (- max-width (length loc)) 6)
+                                        ?\s)
+                           (format "(%s)" ref)))))
+              nil (and retain-labels (cdr code-info)))))))
+    ;; Return value.
+    (format float-env body)))
+
+(defun org-latex-src-block--listings
+    (src-block info lang caption caption-above-p label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((lst-lang
+         (or (cadr (assq (intern lang)
+                         (plist-get info :latex-listings-langs)))
+             lang))
+        (caption-str
+         (when caption
+           (let ((main (org-export-get-caption src-block))
+                 (secondary (org-export-get-caption src-block t)))
+             (if (not secondary)
+                 (format "{%s}" (org-export-data main info))
+               (format "{[%s]%s}"
+                       (org-export-data secondary info)
+                       (org-export-data main info))))))
+        (lst-opt (plist-get info :latex-listings-options)))
+    (concat
+     ;; Options.
+     (format
+      "\\lstset{%s}\n"
+      (concat
+       (org-latex--make-option-string
+        (append
+         lst-opt
+         (cond
+          ((and (not float) (plist-member attributes :float)) nil)
+          ((string= "multicolumn" float) '(("float" "*")))
+          ((and float (not (assoc "float" lst-opt)))
+           `(("float" ,(plist-get info :latex-default-figure-position)))))
+         `(("language" ,lst-lang))
+         (if label
+             `(("label" ,(org-latex--label src-block info)))
+           '(("label" " ")))
+         (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
+         `(("captionpos" ,(if caption-above-p "t" "b")))
+         (cond ((assoc "numbers" lst-opt) nil)
+               ((not num-start) '(("numbers" "none")))
+               (t `(("firstnumber" ,(number-to-string (1+ num-start)))
+                    ("numbers" "left"))))))
+       (let ((local-options (plist-get attributes :options)))
+         (and local-options (concat "," local-options)))))
+     ;; Source code.
+     (format
+      "\\begin{lstlisting}\n%s\\end{lstlisting}"
+      (let* ((code-info (org-export-unravel-code src-block))
+             (max-width
+              (apply 'max
+                     (mapcar 'length
+                             (org-split-string (car code-info) "\n")))))
+        (org-export-format-code
+         (car code-info)
+         (lambda (loc _num ref)
+           (concat
+            loc
+            (when ref
+              ;; Ensure references are flushed to the right,
+              ;; separated with 6 spaces from the widest line of
+              ;; code
+              (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
+                      (format "(%s)" ref)))))
+         nil (and retain-labels (cdr code-info))))))))
 
 ;;;; Statistics Cookie
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-ox-latex-Refactor-org-latex-inline-src-block.patch --]
[-- Type: text/x-patch, Size: 4018 bytes --]

From 6635b72356192c3b0be500984b327d0b4ebd8e2b Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 18:53:10 +0800
Subject: [PATCH 02/13] ox-latex: Refactor `org-latex-inline-src-block'

* lisp/ox-latex.el (org-latex-inline-src-block,
org-latex-inline-src-block--minted,
org-latex-inline-src-block--listings): Extract the minted and listings
specific logic out of `org-latex-inline-src-block` into the new
functions `org-latex-inline-src-block--minted` and
`org-latex-inline-src-block--listings`.
---
 lisp/ox-latex.el | 62 +++++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index c2f728a1c..38f36a1f3 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2127,36 +2127,38 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
   "Transcode an INLINE-SRC-BLOCK element from Org to LaTeX.
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
-  (let* ((code (org-element-property :value inline-src-block))
-	 (separator (org-latex--find-verb-separator code)))
-    (cl-case (plist-get info :latex-listings)
-      ;; Do not use a special package: transcode it verbatim, as code.
-      ((nil) (org-latex--text-markup code 'code info))
-      ;; Use minted package.
-      (minted
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (mint-lang (or (cadr (assq (intern org-lang)
-					 (plist-get info :latex-minted-langs)))
-			     (downcase org-lang)))
-	      (options (org-latex--make-option-string
-			(plist-get info :latex-minted-options))))
-	 (format "\\mintinline%s{%s}{%s}"
-		 (if (string= options "") "" (format "[%s]" options))
-		 mint-lang
-		 code)))
-      ;; Use listings package.
-      (otherwise
-       ;; Maybe translate language's name.
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (lst-lang (or (cadr (assq (intern org-lang)
-					(plist-get info :latex-listings-langs)))
-			    org-lang))
-	      (options (org-latex--make-option-string
-			(append (plist-get info :latex-listings-options)
-				`(("language" ,lst-lang))))))
-	 (concat (format "\\lstinline[%s]" options)
-		 separator code separator))))))
-
+  (let ((code (org-element-property :value inline-src-block))
+        (lang (org-element-property :language inline-src-block)))
+    (pcase (plist-get info :latex-listings)
+      ('nil (org-latex--text-markup code 'code info))
+      ('minted (org-latex-inline-src-block--minted info code lang))
+      (_ (org-latex-inline-src-block--listings info code lang)))))
+
+(defun org-latex-inline-src-block--minted (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using minted.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let ((mint-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-minted-langs)))
+                       (downcase lang)))
+        (options (org-latex--make-option-string
+                  (plist-get info :latex-minted-options))))
+    (format "\\mintinline%s{%s}{%s}"
+            (if (string= options "") "" (format "[%s]" options))
+            mint-lang
+            code)))
+
+(defun org-latex-inline-src-block--listings (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let* ((lst-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-listings-langs)))
+                       lang))
+         (separator (org-latex--find-verb-separator code))
+         (options (org-latex--make-option-string
+                   (append (plist-get info :latex-listings-options)
+                           `(("language" ,lst-lang))))))
+    (concat (format "\\lstinline[%s]" options)
+            separator code separator)))
 
 ;;;; Inlinetask
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-ox-latex-More-versitile-option-construction.patch --]
[-- Type: text/x-patch, Size: 4118 bytes --]

From 108f321a80de89c72974fc25fcde36c85023daca Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 23:31:59 +0800
Subject: [PATCH 03/13] ox-latex: More versitile option construction

* lisp/ox-latex.el (org-latex--make-option-string): Support a custom
option seperator string.

(org-latex--make-option-string, org-latex-minted-options,
org-latex-listings-options): The first line of the docstrings for
`org-latex-minted-options` and `org-latex-listings-options` describe the
variables as "association lists", yet `org-latex--make-option-string`
does not handle association lists and an example of two-value lists is
provided.  To make the behaviour match the docstring,
`org-latex--make-option-string` is modified to work with either a list
two-value lists or an association list, and the examples in
`org-latex-minted-options` and `org-latex-listings-options` updated
accordingly.
---
 lisp/ox-latex.el | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 38f36a1f3..2d4b3bace 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1006,12 +1006,16 @@ (defcustom org-latex-listings-options nil
 
 These options are supplied as a comma-separated list to the
 \\lstset command.  Each element of the association list should be
-a list containing two strings: the name of the option, and the
-value.  For example,
+a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-listings-options
     \\='((\"basicstyle\" \"\\\\small\")
       (\"keywordstyle\" \"\\\\color{black}\\\\bfseries\\\\underbar\")))
+  ; or
+  (setq org-latex-listings-options
+    \\='((\"basicstyle\" . \"\\\\small\")
+      (\"keywordstyle\" . \"\\\\color{black}\\\\bfseries\\\\underbar\")))
 
 will typeset the code in a small size font with underlined, bold
 black keywords.
@@ -1059,11 +1063,14 @@ (defcustom org-latex-minted-options nil
 
 These options are supplied within square brackets in
 \\begin{minted} environments.  Each element of the alist should
-be a list containing two strings: the name of the option, and the
-value.  For example,
+be a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-minted-options
     \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-minted-options
+    \\='((\"bgcolor\" . \"bg\") (\"frame\" . \"lines\")))
 
 will result in source blocks being exported with
 
@@ -1506,21 +1513,24 @@ (defun org-latex--find-verb-separator (s)
 	     when (not (string-match (regexp-quote (char-to-string c)) s))
 	     return (char-to-string c))))
 
-(defun org-latex--make-option-string (options)
+(defun org-latex--make-option-string (options &optional seperator)
   "Return a comma separated string of keywords and values.
 OPTIONS is an alist where the key is the options keyword as
 a string, and the value a list containing the keyword value, or
 nil."
   (mapconcat (lambda (pair)
-	       (pcase-let ((`(,keyword ,value) pair))
-		 (concat keyword
-			 (and (> (length value) 0)
-			      (concat "="
-                                      (if (string-match-p (rx (any "[]")) value)
-                                          (format "{%s}" value)
-                                        value))))))
-	     options
-	     ","))
+               (let ((keyword (car pair))
+                     (value (pcase (cdr pair)
+                              ((pred stringp) (cdr pair))
+                              ((pred consp) (cadr pair)))))
+                 (concat keyword
+                         (when value
+                           (concat "="
+                                   (if (string-match-p (rx (any "[]")) value)
+                                       (format "{%s}" value)
+                                     value))))))
+             options
+             (or seperator ",")))
 
 (defun org-latex--wrap-label (element output info)
   "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-ox-latex-Introduce-engraved-code-highlighting.patch --]
[-- Type: text/x-patch, Size: 17857 bytes --]

From ac29f0f3991faf457f161698b4ad311edfe5d55d Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 20:04:12 +0800
Subject: [PATCH 04/13] ox-latex: Introduce "engraved" code highlighting

* lisp/ox-latex.el (org-latex-src-block, org-latex-src-block--engraved,
org-latex-inline-src-block, org-latex-inline-src-block--engraved,
org-latex-src--engrave-code, org-latex-template, org-latex-listings):
Make use of the engraved-faces package (available on ELPA) to provide an
alternative LaTeX code highlighting backend which functions similarly to
htmlize.el for HTML exports.

(org-latex-engraved-preamble, org-latex-engraved-options): Introduce
variables to construct the preamble for engraved code blocks.

* lisp/ox-beamer.el (org-beamer-template): Modify to add engrave-faces
preamble when applicable.
---
 lisp/ox-beamer.el |   6 +
 lisp/ox-latex.el  | 292 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 289 insertions(+), 9 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 6be73c91e..fe73bf686 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -857,6 +857,12 @@ (defun org-beamer-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
+     ;; engrave-faces-latex preamble
+     (when (and (eq org-latex-listings 'engraved)
+                (org-element-map (plist-get info :parse-tree)
+                    '(src-block inline-src-block) #'identity
+                    info t))
+       (org-latex-generate-engraved-preamble info t))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 2d4b3bace..e0f47cf80 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -37,6 +37,8 @@ (defvar org-latex-default-packages-alist)
 (defvar org-latex-packages-alist)
 (defvar orgtbl-exp-regexp)
 
+(declare-function engrave-faces-latex-gen-preamble "ext:engrave-faces-latex")
+(declare-function engrave-faces-latex-buffer "ext:engrave-faces-latex")
 
 \f
 ;;; Define Back-End
@@ -125,6 +127,8 @@ (org-export-define-backend 'latex
     (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
     (:latex-default-table-mode nil nil org-latex-default-table-mode)
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
+    (:latex-engraved-options nil nil org-latex-engraved-options)
+    (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -937,22 +941,48 @@ (defcustom org-latex-listings nil
   "Non-nil means export source code using the listings package.
 
 This package will fontify source code, possibly even with color.
-If you want to use this, you also need to make LaTeX use the
-listings package, and if you want to have color, the color
-package.  Just add these to `org-latex-packages-alist', for
-example using customize, or with something like:
+There are four implementations of this functionality you may
+choose from (ordered from least to most capable):
+1. Verbatim (nil)
+2. Listings (t)
+3. Minted (minted)
+4. Engraved (engraved)
+
+The first two options provide basic syntax
+highlighting (listings), or none at all (verbatim).
+
+When using listings, you also need to make use of the LaTeX
+\"listings\" package. The \"color\" package is also needed if you
+would like color too.  These can simply be added to
+`org-latex-packages-alist', using customise or something like:
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\"))
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\"))
 
-Alternatively,
+There are two further options for more comprehensive
+fontification. The first can be set with,
+
+  (setq org-latex-listings \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the engrave-faces
+package (availible from ELPA), and the fvextra LaTeX package be
+installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the tcolorbox LaTeX package in
+addition to fvextra.
+
+The second more comprehensive option can be set with,
 
   (setq org-latex-listings \\='minted)
 
-causes source code to be exported using the minted package as
-opposed to listings.  If you want to use minted, you need to add
-the minted package to `org-latex-packages-alist', for example
+which causes source code to be exported using the minted package
+as opposed to listings.  If you want to use minted, you need to
+add the minted package to `org-latex-packages-alist', for example
 using customize, or with
 
   (require \\='ox-latex)
@@ -971,8 +1001,9 @@ (defcustom org-latex-listings nil
   :type '(choice
 	  (const :tag "Use listings" t)
 	  (const :tag "Use minted" minted)
+	  (const :tag "Use engrave-faces-latex" engraved)
 	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted))))
+  :safe (lambda (s) (memq s '(t nil minted engraved))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1142,6 +1173,151 @@ (defcustom org-latex-custom-lang-environments nil
   :version "26.1"
   :package-version '(Org . "9.0"))
 
+(defcustom org-latex-engraved-preamble
+  "\\usepackage{fvextra}
+
+[FVEXTRA-SETUP]
+
+% Make line numbers smaller and grey.
+\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
+
+\\usepackage{xcolor}
+
+% In case engrave-faces-latex-gen-preamble has not been run.
+\\providecolor{EfD}{HTML}{f7f7f7}
+\\providecolor{EFD}{HTML}{28292e}
+
+% Define a Code environment to prettily wrap the fontified code.
+\\usepackage[breakable,xparse]{tcolorbox}
+\\DeclareTColorBox[]{Code}{o}%
+{colback=EfD!98!EFD, colframe=EfD!95!EFD,
+  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
+  colupper=EFD,
+  IfNoValueTF={#1}%
+  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
+    boxrule=0.5pt, left=2pt}%
+  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
+    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
+  right=2pt, top=1pt, bottom=0.5pt,
+  breakable}
+
+[LISTINGS-SETUP]"
+  "Preamble content injected when using engrave-faces-latex for source blocks.
+This is relevant when `org-latex-listings' is set to `engraved'.
+
+There is quite a lot of flexibility in what this preamble can be,
+as long as it:
+- Loads the fvextra package.
+- Loads the package xcolor (if it is not already loaded elsewhere).
+- Defines a \"Code\" environment (note the capital C), which all
+  \"Verbatim\" environments (provided by fvextra) will be wrapped with.
+
+In the default value the colors \"EFD\" and \"EfD\" are provided
+as they are respectively the foreground and background colours,
+just in case they aren't provided by the generated preamble, so
+we can asume they are always set.
+
+Within this preamble there are two recognised macro-like placeholders:
+
+  [FVEXTRA-SETUP]
+
+  [LISTINGS-SETUP]
+
+Unless you have a very good reason, both of these placeholders
+should be included in the preamble.
+
+FVEXTRA-SETUP sets fvextra's defaults according to
+`org-latex-engraved-options', and LISTINGS-SETUP creates the
+listings environment used for captioned or floating code blocks,
+as well as defining \\listoflistings."
+  :group 'org-export-latex
+  :type 'string
+  :package-version '(Org . "9.6"))
+
+(defcustom org-latex-engraved-options
+  '(("commandchars" . "\\\\\\{\\}")
+    ("highlightcolor" . "white!95!black!80!blue")
+    ("breaklines" . "true")
+    ("breaksymbol" . "\\color{white!60!black}\\tiny\\ensuremath{\\hookrightarrow}"))
+  "Association list of options for the latex fvextra package when engraving code.
+
+These options are set using \\fvset{...} in the preamble of the
+LaTeX export.  Each element of the alist should be a list or cons
+cell containing two strings: the name of the option, and the
+value.  For example,
+
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" \"green\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" . \"green\") (\"frame\" . \"lines\")))
+
+will result in the following LaTeX in the preamble
+
+\\fvset{%
+  bgcolor=bg,
+  frame=lines}
+
+This will affect all fvextra environments.  Note that the same
+options will be applied to all blocks.  If you need
+block-specific options, you may use the following syntax:
+
+  #+ATTR_LATEX: :options key1=value1,key2=value2
+  #+BEGIN_SRC <LANG>
+  ...
+  #+END_SRC"
+  :group 'org-export-latex
+  :type '(alist :key-type (string :tag "option")
+                :value-type (string :tag "value")))
+
+(defun org-latex-generate-engraved-preamble (info syntax-colours-p)
+  "Generate the preamble to setup engraved code.
+The result is constructed from the :latex-engraved-preamble and
+:latex-engraved-optionsn export options, the default values of
+which are given by `org-latex-engraved-preamble' and
+`org-latex-engraved-options' respectively."
+  (let* ((engraved-options
+          (plist-get info :latex-engraved-options))
+         (engraved-preamble (plist-get info :latex-engraved-preamble)))
+    (when (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?" engraved-preamble)
+      (setq engraved-preamble
+            (replace-match
+             (concat
+              "\\fvset{%\n  "
+              (org-latex--make-option-string engraved-options ",\n  ")
+              "}\n")
+             t t
+             engraved-preamble)))
+    (when (string-match "^[ \t]*\\[LISTINGS-SETUP\\][ \t]*\n?" engraved-preamble)
+      (setq engraved-preamble
+            (replace-match
+             (format
+              "%% Support listings with captions
+\\usepackage{float}
+\\floatstyle{%s}
+\\newfloat{listing}{htbp}{lst}
+\\newcommand{\\listingsname}{Listing}
+\\floatname{listing}{\\listingsname}
+\\newcommand{\\listoflistingsname}{List of Listings}
+\\providecommand{\\listoflistings}{\\listof{listing}{\\listoflistingsname}}\n"
+              (if (memq 'src-block org-latex-caption-above)
+                  "plaintop" "plain"))
+             t t
+             engraved-preamble)))
+    (if syntax-colours-p
+        (concat
+         "\n% Setup for code blocks [1/2]\n\n"
+         engraved-preamble
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         (if (require 'engrave-faces-latex nil t)
+             (engrave-faces-latex-gen-preamble)
+           (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
+           "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
+         "\n")
+      (concat
+       "\n% Setup for code blocks\n\n"
+       engraved-preamble
+       "\n"))))
 
 ;;;; Compilation
 
@@ -1756,6 +1932,12 @@ (defun org-latex-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
             (format-spec template spec)))
+     ;; engrave-faces-latex preamble
+     (when (and (eq org-latex-listings 'engraved)
+                (org-element-map (plist-get info :parse-tree)
+                    '(src-block inline-src-block) #'identity
+                    info t))
+       (org-latex-generate-engraved-preamble info t))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
@@ -2142,6 +2324,7 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
     (pcase (plist-get info :latex-listings)
       ('nil (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
+      ('engraved (org-latex-inline-src-block--engraved info code lang))
       (_ (org-latex-inline-src-block--listings info code lang)))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
@@ -2157,6 +2340,11 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
+(defun org-latex-inline-src-block--engraved (_info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (format "\\Verb{%s}" (org-latex-src--engrave-code code lang)))
+
 (defun org-latex-inline-src-block--listings (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
@@ -2323,6 +2511,7 @@ (defun org-latex-keyword (keyword _contents info)
 	  (cl-case (plist-get info :latex-listings)
 	    ((nil) "\\listoffigures")
 	    (minted "\\listoflistings")
+	    (engraved "\\listoflistings")
 	    (otherwise "\\lstlistoflistings")))))))))
 
 
@@ -3017,6 +3206,9 @@ (defun org-latex-src-block (src-block _contents info)
                                      num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
         (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float))
+       ((eq listings 'engraved)
+        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
                                        num-start retain-labels attributes float))
        (t
         (org-latex-src-block--listings src-block info lang caption caption-above-p label
@@ -3133,6 +3325,88 @@ (defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
+(defun org-latex-src--engrave-code (content lang)
+  "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result."
+  (if (require 'engrave-faces-latex nil t)
+      (let* ((lang-mode (and lang (org-src-get-lang-mode lang)))
+             (engraved-buffer
+              (with-temp-buffer
+                (insert content)
+                (when lang-mode
+                  (if (functionp lang-mode)
+                      (funcall lang-mode)
+                    (message "Cannot engrave code as %s. %s is undefined."
+                             lang lang-mode)))
+                (engrave-faces-latex-buffer)))
+             (engraved-code
+              (with-current-buffer engraved-buffer
+                (buffer-string))))
+        (kill-buffer engraved-buffer)
+        engraved-code)
+    (user-error "Cannot engrave code as `engrave-faces-latex' is unavailible.")))
+
+(defun org-latex-src-block--engraved
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-engraved-options))
+         (content
+          (let* ((code-info (org-export-unravel-code src-block))
+                 (max-width
+                  (apply 'max
+                         (mapcar 'string-width
+                                 (org-split-string (car code-info)
+                                                   "\n")))))
+            (org-export-format-code
+             (car code-info)
+             (lambda (loc _num ref)
+               (concat
+                loc
+                (when ref
+                  ;; Ensure references are flushed to the right,
+                  ;; separated with 6 spaces from the widest line
+                  ;; of code.
+                  (concat (make-string (+ (- max-width (length loc)) 6)
+                                       ?\s)
+                          (format "(%s)" ref)))))
+             nil (and retain-labels (cdr code-info)))))
+         (body
+          (format
+           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (append
+              (when (and num-start (not (assoc "linenos" options)))
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start)))))
+              (let ((local-options (plist-get attributes :options)))
+                (and local-options (list local-options))))))
+           (org-latex-src--engrave-code content lang))))
+    (format float-env body)))
+
 (defun org-latex-src-block--listings
     (src-block info lang caption caption-above-p label
                num-start retain-labels attributes float)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-ox-latex-Don-t-use-length-to-get-string-width.patch --]
[-- Type: text/x-patch, Size: 1539 bytes --]

From 815de46384a566b3dcd86061b9aa93563a7acb29 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 13:59:13 +0800
Subject: [PATCH 05/13] ox-latex: Don't use `length' to get string width

* lisp/ox-latex.el (org-latex-src-block--listings,
org-latex-src-block--engraved, org-latex-src-block--minted): Use
`string-width' instead of `length' to gauge the displayed width of the
string in LaTeX.  This may not be a perfect match, but it should be an
improvement.
---
 lisp/ox-latex.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index e0f47cf80..0788b40c0 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3306,7 +3306,7 @@ (defun org-latex-src-block--minted
            (let* ((code-info (org-export-unravel-code src-block))
                   (max-width
                    (apply 'max
-                          (mapcar 'length
+                          (mapcar 'string-width
                                   (org-split-string (car code-info)
                                                     "\n")))))
              (org-export-format-code
@@ -3458,7 +3458,7 @@ (defun org-latex-src-block--listings
       (let* ((code-info (org-export-unravel-code src-block))
              (max-width
               (apply 'max
-                     (mapcar 'length
+                     (mapcar 'string-width
                              (org-split-string (car code-info) "\n")))))
         (org-export-format-code
          (car code-info)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: 0006-ox-latex-Refactor-source-block-transcode-fun-sigs.patch --]
[-- Type: text/x-patch, Size: 7299 bytes --]

From fadf2011884d0e46b5442ec43dc942050e2fd048 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 14:02:44 +0800
Subject: [PATCH 06/13] ox-latex: Refactor source block transcode fun sigs

* lisp/ox-latex.el (org-latex-src-block--listings,
org-latex-src-block--engraved, org-latex-src-block--minted,
org-latex-src-block--custom): Refactor these --backend functions to use
cl-defun with keys instead of having an 11-argument signature.
(org-latex-src-block): Adjust for the change in signature of the
--backend functions, and refactor the `cond' statement to use `pcase'.
---
 lisp/ox-latex.el | 82 +++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 43 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 0788b40c0..4a077bb27 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3186,37 +3186,37 @@ (defun org-latex-src-block (src-block _contents info)
 contextual information."
   (when (org-string-nw-p (org-element-property :value src-block))
     (let* ((lang (org-element-property :language src-block))
-	   (caption (org-element-property :caption src-block))
-	   (caption-above-p (org-latex--caption-above-p src-block info))
-	   (label (org-element-property :name src-block))
-	   (custom-env (and lang
-			    (cadr (assq (intern lang)
-					org-latex-custom-lang-environments))))
-	   (num-start (org-export-get-loc src-block info))
-	   (retain-labels (org-element-property :retain-labels src-block))
-	   (attributes (org-export-read-attribute :attr_latex src-block))
-	   (float (plist-get attributes :float))
-	   (listings (plist-get info :latex-listings)))
-      (cond
-       ((or (not lang) (not listings))
-        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))
-       (custom-env
-        (org-latex-src-block--custom src-block info lang caption caption-above-p label
-                                     num-start retain-labels attributes float custom-env))
-       ((eq listings 'minted)
-        (org-latex-src-block--minted src-block info lang caption caption-above-p label
-                                     num-start retain-labels attributes float))
-       ((eq listings 'engraved)
-        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))
-       (t
-        (org-latex-src-block--listings src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))))))
-
-(defun org-latex-src-block--verbatim
-    (src-block info _lang caption caption-above-p _label
-               _num-start _retain-labels _attributes float)
+           (caption (org-element-property :caption src-block))
+           (caption-above-p (org-latex--caption-above-p src-block info))
+           (label (org-element-property :name src-block))
+           (custom-env (and lang
+                            (cadr (assq (intern lang)
+                                        org-latex-custom-lang-environments))))
+           (num-start (org-export-get-loc src-block info))
+           (retain-labels (org-element-property :retain-labels src-block))
+           (attributes (org-export-read-attribute :attr_latex src-block))
+           (float (plist-get attributes :float))
+           (listings (plist-get info :latex-listings)))
+      (funcall
+       (pcase listings
+         ((or (pred not) (guard (not lang))) #'org-latex-src-block--verbatim)
+         ((guard custom-env) #'org-latex-src-block--custom)
+         ('minted #'org-latex-src-block--minted)
+         ('engraved #'org-latex-src-block--engraved)
+         (_ #'org-latex-src-block--listings))
+       :src-block src-block
+       :info info
+       :lang lang
+       :caption caption
+       :caption-above-p caption-above-p
+       :label label
+       :num-start num-start
+       :retain-labels retain-labels
+       :attributes attributes
+       :float float))))
+
+(cl-defun org-latex-src-block--verbatim
+    (&key src-block info caption caption-above-p float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3235,9 +3235,8 @@ (defun org-latex-src-block--verbatim
                     (if caption-above-p "" (concat "\n" caption-str))))
           (t verbatim))))
 
-(defun org-latex-src-block--custom
-    (src-block info _lang caption caption-above-p _label
-               _num-start _retain-labels attributes float custom-env)
+(cl-defun org-latex-src-block--custom
+    (&key src-block info caption caption-above-p attributes float custom-env &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3257,9 +3256,8 @@ (defun org-latex-src-block--custom
                      (?l . ,(org-latex--label src-block info))
                      (?o . ,(or (plist-get attributes :options) "")))))))
 
-(defun org-latex-src-block--minted
-    (src-block info lang caption caption-above-p _label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--minted
+    (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3345,9 +3343,8 @@ (defun org-latex-src--engrave-code (content lang)
         engraved-code)
     (user-error "Cannot engrave code as `engrave-faces-latex' is unavailible.")))
 
-(defun org-latex-src-block--engraved
-    (src-block info lang caption caption-above-p _label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--engraved
+    (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3407,9 +3404,8 @@ (defun org-latex-src-block--engraved
            (org-latex-src--engrave-code content lang))))
     (format float-env body)))
 
-(defun org-latex-src-block--listings
-    (src-block info lang caption caption-above-p label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--listings
+    (&key src-block info lang caption caption-above-p label num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #8: 0007-ox-latex-Replace-org-latex-listings.patch --]
[-- Type: text/x-patch, Size: 16239 bytes --]

From e6dfd941daf06beb859ae6effd0be9d734121897 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 14:46:28 +0800
Subject: [PATCH 07/13] ox-latex: Replace `org-latex-listings'

* lisp/ox-latex.el (org-latex-src-block, org-latex-keyword,
org-latex-inline-src-block, org-latex-template,
org-latex--caption/label-string, org-latex-engraved-preamble,
org-latex-listings): Replace `org-latex-listings' with
`org-latex-src-block-backend', which now can be set to listings/verbatim
and no longer advertises t/nil as valid values.

* lisp/ox-beamer.el (org-beamer-template): Update in the same manner as
`org-latex-template'.

* lisp/org-compat.el: Make `org-latex-listings' an obsolete alias for
`org-latex-src-block-backend'.

* testing/lisp/test-ox.el: Replace `org-latex-listings' reference with
`org-latex-src-block-backend'.

* doc/org-manual.org (Footnotes, LaTeX specific properties, Literal
Examples): Replace references to `org-latex-listings' with
`org-latex-src-block-backend'.

* etc/ORG-NEWS: Add a news entry noting this change.

The variable `org-latex-listings' originally indicated whether source
blocks should use the listings LaTeX package, or not.  This usage has
evolved over the years, and now it sets one of four different
fontification backends.  This renaming should make the variable name a
bit less misleading.
---
 doc/org-manual.org      |   6 +--
 etc/ORG-NEWS            |   9 ++++
 lisp/org-compat.el      |   2 +
 lisp/ox-beamer.el       |   2 +-
 lisp/ox-latex.el        | 117 ++++++++++++++++++++++------------------
 testing/lisp/test-ox.el |   2 +-
 6 files changed, 81 insertions(+), 57 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index c0d38cd8c..60bded419 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -11159,7 +11159,7 @@ ** Literal Examples
 #+end_example
 
 #+cindex: formatting source code, markup rules
-#+vindex: org-latex-listings
+#+vindex: org-latex-src-block-backend
 If the example is source code from a programming language, or any
 other text that can be marked up by Font Lock in Emacs, you can ask
 for the example to look like the fontified Emacs buffer[fn:114].  This
@@ -16304,12 +16304,12 @@ **** LaTeX specific properties
 | ~:latex-link-with-unknown-path-format~ | ~org-latex-link-with-unknown-path-format~ |
 | ~:latex-listings-langs~                | ~org-latex-listings-langs~                |
 | ~:latex-listings-options~              | ~org-latex-listings-options~              |
-| ~:latex-listings~                      | ~org-latex-listings~                      |
 | ~:latex-minted-langs~                  | ~org-latex-minted-langs~                  |
 | ~:latex-minted-options~                | ~org-latex-minted-options~                |
 | ~:latex-prefer-user-labels~            | ~org-latex-prefer-user-labels~            |
 | ~:latex-subtitle-format~               | ~org-latex-subtitle-format~               |
 | ~:latex-subtitle-separate~             | ~org-latex-subtitle-separate~             |
+| ~:latex-src-block-backend~             | ~org-latex-src-block-backend~             |
 | ~:latex-table-scientific-notation~     | ~org-latex-table-scientific-notation~     |
 | ~:latex-tables-booktabs~               | ~org-latex-tables-booktabs~               |
 | ~:latex-tables-centered~               | ~org-latex-tables-centered~               |
@@ -22256,7 +22256,7 @@ * Footnotes
 version 1.34 of the =htmlize.el= package, which you need to install).
 Fontified code chunks in LaTeX can be achieved using either the
 [[https://www.ctan.org/pkg/listings][listings]] package or the [[https://www.ctan.org/pkg/minted][minted]] package.  Refer to
-~org-latex-listings~ for details.
+~org-latex-src-block-backend~ for details.
 
 [fn:115] Source code in code blocks may also be evaluated either
 interactively or on export.  See [[*Working with Source Code]] for more
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 27de6da62..ebb3cd649 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -273,6 +273,15 @@ Chmod-style permissions are based on the new variable
 ~org-babel-tangle-default-file-mode~.
 
 *** A new custom setting =org-agenda-clock-report-header= to add a header to org agenda clock report
+
+*** ~org-latex-listings~ has been replaced with ~org-latex-src-block-backend~
+
+~org-latex-listings~ has been renamed to better reflect the current
+purpose of the variable.  The replacement variable
+~org-latex-src-block-backend~ acts in exactly the same way, however it
+accepts =listings= and =verbatim= in place of =t= and =nil= (which
+still work, but are no longer listed as valid options).
+
 * Version 9.5
 
 ** Important announcements and breaking changes
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index a29f206a4..704197645 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -324,6 +324,8 @@ (define-obsolete-variable-alias 'org-latex-create-formula-image-program
   'org-preview-latex-default-process "9.0")
 (define-obsolete-variable-alias 'org-latex-preview-ltxpng-directory
   'org-preview-latex-image-directory "9.0")
+(define-obsolete-variable-alias 'org-latex-listings
+  'org-latex-src-block-backend "9.6")
 (define-obsolete-function-alias 'org-table-p 'org-at-table-p "9.0")
 (define-obsolete-function-alias 'org-on-heading-p 'org-at-heading-p "9.0")
 (define-obsolete-function-alias 'org-at-regexp-p 'org-in-regexp "8.3")
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index fe73bf686..e6232d8d2 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -858,7 +858,7 @@ (defun org-beamer-template (contents info)
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
      ;; engrave-faces-latex preamble
-     (when (and (eq org-latex-listings 'engraved)
+     (when (and (eq org-latex-src-block-backend 'engraved)
                 (org-element-map (plist-get info :parse-tree)
                     '(src-block inline-src-block) #'identity
                     info t))
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 4a077bb27..f81625b45 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -143,7 +143,7 @@ (org-export-define-backend 'latex
     (:latex-inactive-timestamp-format nil nil org-latex-inactive-timestamp-format)
     (:latex-inline-image-rules nil nil org-latex-inline-image-rules)
     (:latex-link-with-unknown-path-format nil nil org-latex-link-with-unknown-path-format)
-    (:latex-listings nil nil org-latex-listings)
+    (:latex-src-block-backend nil nil org-latex-src-block-backend)
     (:latex-listings-langs nil nil org-latex-listings-langs)
     (:latex-listings-options nil nil org-latex-listings-options)
     (:latex-minted-langs nil nil org-latex-minted-langs)
@@ -937,22 +937,22 @@ (defcustom org-latex-format-inlinetask-function
 
 ;; Src blocks
 
-(defcustom org-latex-listings nil
-  "Non-nil means export source code using the listings package.
+(defcustom org-latex-src-block-backend 'verbatim
+  "Backend used to generate source code listings.
 
-This package will fontify source code, possibly even with color.
-There are four implementations of this functionality you may
+This sets the behaviour for fontifying source code, possibly even with
+color.  There are four implementations of this functionality you may
 choose from (ordered from least to most capable):
-1. Verbatim (nil)
-2. Listings (t)
-3. Minted (minted)
-4. Engraved (engraved)
+1. Verbatim
+2. Listings
+3. Minted
+4. Engraved
 
 The first two options provide basic syntax
 highlighting (listings), or none at all (verbatim).
 
-When using listings, you also need to make use of the LaTeX
-\"listings\" package. The \"color\" package is also needed if you
+When using listings, you also need to make use of LaTeX package
+\"listings\"e. The \"color\" LaTeX package is also needed if you
 would like color too.  These can simply be added to
 `org-latex-packages-alist', using customise or something like:
 
@@ -963,27 +963,12 @@ (defcustom org-latex-listings nil
 There are two further options for more comprehensive
 fontification. The first can be set with,
 
-  (setq org-latex-listings \\='engraved)
+  (setq org-latex-src-block-backend \\='minted)
 
-which causes source code to be run through
-`engrave-faces-latex-buffer', which generates colorings using
-Emacs' font-lock information.  This requires the engrave-faces
-package (availible from ELPA), and the fvextra LaTeX package be
-installed.
-
-The styling of the engraved result can customised with
-`org-latex-engraved-preamble' and `org-latex-engraved-options'.
-The default preamble also uses the tcolorbox LaTeX package in
-addition to fvextra.
-
-The second more comprehensive option can be set with,
-
-  (setq org-latex-listings \\='minted)
-
-which causes source code to be exported using the minted package
-as opposed to listings.  If you want to use minted, you need to
-add the minted package to `org-latex-packages-alist', for example
-using customize, or with
+which causes source code to be exported using the LaTeX package
+minted as opposed to listings.  If you want to use minted, you
+need to add the minted package to `org-latex-packages-alist', for
+example using customize, or with
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"newfloat\" \"minted\"))
@@ -996,14 +981,29 @@ (defcustom org-latex-listings nil
 The minted choice has possible repercussions on the preview of
 latex fragments (see `org-preview-latex-fragment').  If you run
 into previewing problems, please consult
-URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'."
+URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'.
+
+The most comprehensive option can be set with,
+
+  (setq org-latex-src-block-backend \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the Emacs package
+engrave-faces (availible from ELPA), and the LaTeX package
+fvextra be installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the LaTeX package tcolorbox in
+addition to fvextra."
   :group 'org-export-latex
   :type '(choice
-	  (const :tag "Use listings" t)
+	  (const :tag "Use listings" listings)
 	  (const :tag "Use minted" minted)
 	  (const :tag "Use engrave-faces-latex" engraved)
-	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted engraved))))
+	  (const :tag "Export verbatim" verbatim))
+  :safe (lambda (s) (memq s '(listings minted engraved verbatim))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1203,7 +1203,7 @@ (defcustom org-latex-engraved-preamble
 
 [LISTINGS-SETUP]"
   "Preamble content injected when using engrave-faces-latex for source blocks.
-This is relevant when `org-latex-listings' is set to `engraved'.
+This is relevant when `org-latex-src-block-backend' is set to `engraved'.
 
 There is quite a lot of flexibility in what this preamble can be,
 as long as it:
@@ -1526,7 +1526,8 @@ (defun org-latex--caption/label-string (element info)
 			    main)
 		       (and (eq type 'src-block)
 			    (not (plist-get attr :float))
-			    (null (plist-get info :latex-listings)))))
+			    (memq (plist-get info :latex-src-block-backend)
+                                  '(verbatim nil)))))
 	 (short (org-export-get-caption element t))
 	 (caption-from-attr-latex (plist-get attr :caption)))
     (cond
@@ -1546,7 +1547,8 @@ (defun org-latex--caption/label-string (element info)
 		      (paragraph "figure")
 		      (image "figure")
 		      (special-block "figure")
-		      (src-block (if (plist-get info :latex-listings)
+		      (src-block (if (not (memq (plist-get info :latex-src-block-backend)
+                                                '(verbatim nil)))
 				     "listing"
 				   "figure"))
 		      (t (symbol-name type*)))
@@ -1933,7 +1935,7 @@ (defun org-latex-template (contents info)
        (and (stringp template)
             (format-spec template spec)))
      ;; engrave-faces-latex preamble
-     (when (and (eq org-latex-listings 'engraved)
+     (when (and (eq org-latex-src-block-backend 'engraved)
                 (org-element-map (plist-get info :parse-tree)
                     '(src-block inline-src-block) #'identity
                     info t))
@@ -2321,11 +2323,17 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
 contextual information."
   (let ((code (org-element-property :value inline-src-block))
         (lang (org-element-property :language inline-src-block)))
-    (pcase (plist-get info :latex-listings)
-      ('nil (org-latex--text-markup code 'code info))
-      ('minted (org-latex-inline-src-block--minted info code lang))
-      ('engraved (org-latex-inline-src-block--engraved info code lang))
-      (_ (org-latex-inline-src-block--listings info code lang)))))
+    (pcase (plist-get info :latex-src-block-backend)
+      (`verbatim (org-latex--text-markup code 'code info))
+      (`minted (org-latex-inline-src-block--minted info code lang))
+      (`engraved (org-latex-inline-src-block--engraved info code lang))
+      (`listings (org-latex-inline-src-block--listings info code lang))
+      (oldval
+       (message "Please update the LaTeX src-block-backend to %s"
+                (if oldval "listings" "verbatim"))
+       (if oldval
+           (org-latex-inline-src-block--listings info code lang)
+         (org-latex--text-markup code 'code info))))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using minted.
@@ -2508,7 +2516,7 @@ (defun org-latex-keyword (keyword _contents info)
 	      (concat depth (and depth "\n") "\\tableofcontents"))))
 	 ((string-match-p "\\<tables\\>" value) "\\listoftables")
 	 ((string-match-p "\\<listings\\>" value)
-	  (cl-case (plist-get info :latex-listings)
+	  (cl-case (plist-get info :latex-src-block-backend)
 	    ((nil) "\\listoffigures")
 	    (minted "\\listoflistings")
 	    (engraved "\\listoflistings")
@@ -3195,15 +3203,20 @@ (defun org-latex-src-block (src-block _contents info)
            (num-start (org-export-get-loc src-block info))
            (retain-labels (org-element-property :retain-labels src-block))
            (attributes (org-export-read-attribute :attr_latex src-block))
-           (float (plist-get attributes :float))
-           (listings (plist-get info :latex-listings)))
+           (float (plist-get attributes :float)))
       (funcall
-       (pcase listings
-         ((or (pred not) (guard (not lang))) #'org-latex-src-block--verbatim)
+       (pcase (plist-get info :latex-src-block-backend)
+         ((or `verbatim (guard (not lang))) #'org-latex-src-block--verbatim)
+         (`minted #'org-latex-src-block--minted)
+         (`engraved #'org-latex-src-block--engraved)
+         (`listings #'org-latex-src-block--listings)
          ((guard custom-env) #'org-latex-src-block--custom)
-         ('minted #'org-latex-src-block--minted)
-         ('engraved #'org-latex-src-block--engraved)
-         (_ #'org-latex-src-block--listings))
+         (oldval
+          (message "Please update the LaTeX src-block-backend to %s"
+                   (if oldval "listings" "verbatim"))
+          (if oldval
+              #'org-latex-src-block--listings
+            #'org-latex-src-block--verbatim)))
        :src-block src-block
        :info info
        :lang lang
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 25e02b258..28f950813 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -3978,7 +3978,7 @@ (ert-deftest test-org-export/latex-src-block-verbatim-caption ()
 \\end{verbatim}
 \\caption{Caption is below, 60\\%s}
 \\end{figure*}"
-	     (let ((org-latex-listings 'minted) ; inactive due to missing lang
+	     (let ((org-latex-src-block-backend 'minted) ; inactive due to missing lang
 		   (org-latex-default-figure-position "tp"))
 	       ;; Namely "multicolumn" value to get just figure environment
 	       ;; looks like a bug.
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #9: 0008-ox-latex-Support-setting-the-engraved-theme.patch --]
[-- Type: text/x-patch, Size: 3213 bytes --]

From 7bc1f26f126449d8e457d88d6344aa1b5d439dfe Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 8 May 2022 02:01:34 +0800
Subject: [PATCH 08/13] ox-latex: Support setting the engraved theme

* lisp/ox-latex.el (org-latex-generate-engraved-preamble,
org-latex-engraved-theme): Introduce the new export keyword
LATEX_ENGRAVED_THEME with default value given by
`org-latex-engraved-theme'.  This is used to set the engraved theme used
in org-latex-engraved-theme.

This bumps the minimum required version of engrave-faces from v0.2 to
v0.3.
---
 lisp/ox-latex.el | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index f81625b45..e367e9040 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -129,6 +129,7 @@ (org-export-define-backend 'latex
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
     (:latex-engraved-options nil nil org-latex-engraved-options)
     (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
+    (:latex-engraved-theme "LATEX_ENGRAVED_THEME" nil org-latex-engraved-theme)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -1270,6 +1271,14 @@ (defcustom org-latex-engraved-options
   :type '(alist :key-type (string :tag "option")
                 :value-type (string :tag "value")))
 
+(defcustom org-latex-engraved-theme nil
+  "The theme that should be used for engraved code, when non-nil.
+This can be set to any theme defined in `engrave-faces-themes' or
+loadable by Emacs.  When set to t, the current Emacs theme is
+used.  When nil, no theme is applied."
+  :group 'org-export-latex
+  :type 'symbol)
+
 (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
   "Generate the preamble to setup engraved code.
 The result is constructed from the :latex-engraved-preamble and
@@ -1278,7 +1287,8 @@ (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
 `org-latex-engraved-options' respectively."
   (let* ((engraved-options
           (plist-get info :latex-engraved-options))
-         (engraved-preamble (plist-get info :latex-engraved-preamble)))
+         (engraved-preamble (plist-get info :latex-engraved-preamble))
+         (engraved-theme (plist-get info :latex-engraved-theme)))
     (when (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?" engraved-preamble)
       (setq engraved-preamble
             (replace-match
@@ -1310,7 +1320,8 @@ (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
          engraved-preamble
          "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
          (if (require 'engrave-faces-latex nil t)
-             (engrave-faces-latex-gen-preamble)
+             (engrave-faces-latex-gen-preamble
+              (when engraved-theme (intern engraved-theme)))
            (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
            "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
          "\n")
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #10: 0009-ox-latex-Support-setting-engraved-theme-per-block.patch --]
[-- Type: text/x-patch, Size: 9236 bytes --]

From 24db3cc69c2e28e4207532ac5181e27a28456eae Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 8 May 2022 15:28:29 +0800
Subject: [PATCH 09/13] ox-latex: Support setting engraved theme per-block

* lisp/ox-latex.el (org-latex-src-block--engraved,
org-latex-src--engrave-code, org-latex-inline-src-block--engraved,
org-latex-generate-engraved-preamble): Allow for the engraved theme used
to be set on a per-src-block basis with #+attr_latex: :engraved-theme
THEME.  Extra setup code is now generated in
`org-latex-generate-engraved-preamble'.  To facilitate the application
of themes to src blocks, `org-latex-src--engrave-code' now takes on a
larger portion of the transcoding work.
---
 lisp/ox-latex.el | 120 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 96 insertions(+), 24 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index e367e9040..9634461bd 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1288,7 +1288,27 @@ (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
   (let* ((engraved-options
           (plist-get info :latex-engraved-options))
          (engraved-preamble (plist-get info :latex-engraved-preamble))
-         (engraved-theme (plist-get info :latex-engraved-theme)))
+         (engraved-theme (plist-get info :latex-engraved-theme))
+         (engraved-themes
+          (cl-delete-duplicates
+           (org-element-map
+               (plist-get info :parse-tree)
+               '(src-block inline-src-block)
+             (lambda (src)
+               (plist-get
+                (org-export-read-attribute :attr_latex src)
+                :engraved-theme))
+             info)))
+         (gen-theme-spec
+          (lambda (theme)
+            (if (eq engrave-faces-latex-output-style 'preset)
+                (engrave-faces-latex-gen-preamble (when theme (intern theme)))
+              (engrave-faces-latex-gen-preamble-line
+               'default
+               (alist-get 'default
+                          (if theme
+                              (engrave-faces-get-theme (intern theme))
+                            engrave-faces-current-preset-style)))))))
     (when (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?" engraved-preamble)
       (setq engraved-preamble
             (replace-match
@@ -1318,10 +1338,31 @@ (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
         (concat
          "\n% Setup for code blocks [1/2]\n\n"
          engraved-preamble
-         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n\n"
          (if (require 'engrave-faces-latex nil t)
-             (engrave-faces-latex-gen-preamble
-              (when engraved-theme (intern engraved-theme)))
+             (if engraved-themes
+                 (concat
+                  (mapconcat
+                   (lambda (theme)
+                     (format
+                      "\n\\newcommand{\\engravedtheme%s}{%%\n%s\n}"
+                      (replace-regexp-in-string "[^A-Za-z]" "" theme)
+                      (replace-regexp-in-string
+                       "newcommand" "renewcommand"
+                       (replace-regexp-in-string
+                        "#" "##"
+                        (funcall gen-theme-spec theme)))))
+                   engraved-themes
+                   "\n")
+                  "\n\n"
+                  (cond
+                   ((memq engraved-theme engraved-themes)
+                    (concat "\\engravedtheme"
+                            (replace-regexp-in-string
+                             "[^A-Za-z]" "" engraved-theme)
+                            "\n"))
+                   (t (funcall gen-theme-spec engraved-theme))))
+               (funcall gen-theme-spec engraved-theme))
            (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
            "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
          "\n")
@@ -2359,10 +2400,11 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
-(defun org-latex-inline-src-block--engraved (_info code lang)
+(defun org-latex-inline-src-block--engraved (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
-  (format "\\Verb{%s}" (org-latex-src--engrave-code code lang)))
+  (org-latex-src--engrave-code
+   code lang nil (plist-get info :latex-engraved-options) t))
 
 (defun org-latex-inline-src-block--listings (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
@@ -3347,13 +3389,25 @@ (cl-defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
-(defun org-latex-src--engrave-code (content lang)
-  "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result."
+(defun org-latex-src--engrave-code (content lang &optional theme options inline)
+  "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result.
+When the THEME symbol is non-nil, that theme will be used.
+
+When INLINE is nil, a Verbatim environment wrapped in a Code
+environment will be used. When t, a Verb command will be used.
+
+When OPTIONS is provided, as either a string or list of key-value
+pairs accepted by `org-latex--make-option-string', it is passed
+to the Verbatim environment or Verb command."
   (if (require 'engrave-faces-latex nil t)
       (let* ((lang-mode (and lang (org-src-get-lang-mode lang)))
+             (engrave-faces-current-preset-style
+              (if theme
+                  (engrave-faces-get-theme theme)
+                engrave-faces-current-preset-style))
              (engraved-buffer
               (with-temp-buffer
-                (insert content)
+                (insert (string-trim-right content "\n"))
                 (when lang-mode
                   (if (functionp lang-mode)
                       (funcall lang-mode)
@@ -3362,9 +3416,27 @@ (defun org-latex-src--engrave-code (content lang)
                 (engrave-faces-latex-buffer)))
              (engraved-code
               (with-current-buffer engraved-buffer
-                (buffer-string))))
+                (buffer-string)))
+             (engraved-options
+              (when options
+                (concat "["
+                        (if (listp options)
+                            (org-latex--make-option-string options)
+                          options)
+                        "]")))
+             (engraved-wrapped
+              (if inline
+                  (concat "\\Verb" engraved-options "{" engraved-code "}")
+                (concat "\\begin{Code}\n\\begin{Verbatim}" engraved-options "\n"
+                        engraved-code "\n\\end{Verbatim}\n\\end{Code}"))))
         (kill-buffer engraved-buffer)
-        engraved-code)
+        (if theme
+            (concat "{\\engravedtheme"
+                    (replace-regexp-in-string "[^A-Za-z]" ""
+                                              (symbol-name theme))
+                    engraved-wrapped
+                    "}")
+          engraved-wrapped))
     (user-error "Cannot engrave code as `engrave-faces-latex' is unavailible.")))
 
 (cl-defun org-latex-src-block--engraved
@@ -3392,7 +3464,15 @@ (cl-defun org-latex-src-block--engraved
                             placement)
                     "%s\n\\end{listing}"))
            (t "%s")))
-         (options (plist-get info :latex-engraved-options))
+         (options
+          (let ((engraved-options (plist-get info :latex-engraved-options))
+                (local-options (plist-get attributes :options)))
+            (append
+             (when (and num-start (not (assoc "linenos" engraved-options)))
+               `(("linenos")
+                 ("firstnumber" ,(number-to-string (1+ num-start)))))
+             (and local-options (list local-options)))))
+         (engraved-theme (plist-get attributes :engraved-theme))
          (content
           (let* ((code-info (org-export-unravel-code src-block))
                  (max-width
@@ -3414,18 +3494,10 @@ (cl-defun org-latex-src-block--engraved
                           (format "(%s)" ref)))))
              nil (and retain-labels (cdr code-info)))))
          (body
-          (format
-           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
-           ;; Options.
-           (concat
-            (org-latex--make-option-string
-             (append
-              (when (and num-start (not (assoc "linenos" options)))
-                `(("linenos")
-                  ("firstnumber" ,(number-to-string (1+ num-start)))))
-              (let ((local-options (plist-get attributes :options)))
-                (and local-options (list local-options))))))
-           (org-latex-src--engrave-code content lang))))
+          (org-latex-src--engrave-code
+           content lang
+           (when engraved-theme (intern engraved-theme))
+           options)))
     (format float-env body)))
 
 (cl-defun org-latex-src-block--listings
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #11: 0010-ox-latex-Fix-captions-in-minted-engraved-code.patch --]
[-- Type: text/x-patch, Size: 4986 bytes --]

From 7d9306fe8ada094ff6964422cc527645eb9ffc55 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Mon, 9 May 2022 00:04:10 +0800
Subject: [PATCH 10/13] ox-latex: Fix %-captions in minted/engraved code

* lisp/ox-latex.el (org-latex-src-block--engraved,
org-latex-src-block--minted): Refactor float-env to be clearer, and
switch from `format' to `concat' to fix the bug where %-chars in
captions are interpreted as a format specifier.
---
 lisp/ox-latex.el | 55 +++++++++++++++++++++---------------------------
 1 file changed, 24 insertions(+), 31 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 9634461bd..ceb1bd483 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3330,23 +3330,20 @@ (cl-defun org-latex-src-block--minted
   (let* ((caption-str (org-latex--caption/label-string src-block info))
          (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
                         (plist-get info :latex-default-figure-position)))
+         (multicolumn-p (string= "multicolumn" float))
          (float-env
           (cond
-           ((string= "multicolumn" float)
-            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-                    placement
-                    (if caption-above-p caption-str "")
-                    (if caption-above-p "" caption-str)))
-           (caption
-            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-                    placement
-                    (if caption-above-p caption-str "")
-                    (if caption-above-p "" caption-str)))
+           ((or caption multicolumn-p)
+            (cons
+             (concat "\\begin{listing" (when multicolumn-p "*")
+                     "}[" placement "]\n"
+                     (if caption-above-p caption-str ""))
+             (concat "\n" (if caption-above-p "" caption-str)
+                     "\\end{listing" (when multicolumn-p "*") "}")))
            ((string= "t" float)
-            (concat (format "\\begin{listing}[%s]\n"
-                            placement)
-                    "%s\n\\end{listing}"))
-           (t "%s")))
+            (cons
+             (concat "\\begin{listing}[" placement "]\n")
+             "\n\\end{listing}"))))
          (options (plist-get info :latex-minted-options))
          (body
           (format
@@ -3386,8 +3383,7 @@ (cl-defun org-latex-src-block--minted
                                         ?\s)
                            (format "(%s)" ref)))))
               nil (and retain-labels (cdr code-info)))))))
-    ;; Return value.
-    (format float-env body)))
+    (concat (car float-env) body (cdr float-env))))
 
 (defun org-latex-src--engrave-code (content lang &optional theme options inline)
   "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result.
@@ -3447,23 +3443,20 @@ (cl-defun org-latex-src-block--engraved
   (let* ((caption-str (org-latex--caption/label-string src-block info))
          (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
                         (plist-get info :latex-default-figure-position)))
+         (multicolumn-p (string= "multicolumn" float))
          (float-env
           (cond
-           ((string= "multicolumn" float)
-            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-                    placement
-                    (if caption-above-p caption-str "")
-                    (if caption-above-p "" caption-str)))
-           (caption
-            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-                    placement
-                    (if caption-above-p caption-str "")
-                    (if caption-above-p "" caption-str)))
+           ((or caption multicolumn-p)
+            (cons
+             (concat "\\begin{listing" (when multicolumn-p "*")
+                     "}[" placement "]\n"
+                     (if caption-above-p caption-str ""))
+             (concat "\n" (if caption-above-p "" caption-str)
+                     "\\end{listing" (when multicolumn-p "*") "}")))
            ((string= "t" float)
-            (concat (format "\\begin{listing}[%s]\n"
-                            placement)
-                    "%s\n\\end{listing}"))
-           (t "%s")))
+            (cons
+             (concat "\\begin{listing}[" placement "]\n")
+             "\n\\end{listing}"))))
          (options
           (let ((engraved-options (plist-get info :latex-engraved-options))
                 (local-options (plist-get attributes :options)))
@@ -3498,7 +3491,7 @@ (cl-defun org-latex-src-block--engraved
            content lang
            (when engraved-theme (intern engraved-theme))
            options)))
-    (format float-env body)))
+    (concat (car float-env) body (cdr float-env))))
 
 (cl-defun org-latex-src-block--listings
     (&key src-block info lang caption caption-above-p label num-start retain-labels attributes float &allow-other-keys)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #12: 0011-ox-latex-Support-mathescape-d-code-with-engraved.patch --]
[-- Type: text/x-patch, Size: 3891 bytes --]

From 5fdbbbe811a4d15fa1f7fa4bfad9d3e11e6f4eb8 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 11 May 2022 23:18:19 +0800
Subject: [PATCH 11/13] ox-latex: Support mathescape'd code with engraved

* lisp/ox-latex.el (org-latex-src-block--engraved,
org-latex-src--engrave-mathescape-p): Using the mathescape functionality
in engrave-faces-latex v0.3.1, we can support the mathescape option of
fvextra well.  Along the way, we fix a minor issue with the localoptions
list in `org-latex-src-block--engraved`.
---
 lisp/ox-latex.el | 46 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 5 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index ceb1bd483..29543f8e9 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3385,6 +3385,40 @@ (cl-defun org-latex-src-block--minted
               nil (and retain-labels (cdr code-info)))))))
     (concat (car float-env) body (cdr float-env))))
 
+(defun org-latex-src--engrave-mathescape-p (info options)
+  "From the export INFO plist, and the per-block OPTIONS, determine mathescape."
+  (let ((default-options (plist-get info :latex-engraved-options))
+        (mathescape-status
+         (lambda (opts)
+           (cl-some
+            (lambda (opt)
+              (or (and
+                   (null (cdr opt))
+                   (cond
+                    ((string-match-p
+                      "\\(?:^\\|,\\)mathescape=false\\(?:,\\|$\\)"
+                      (car opt))
+                     'no)
+                    ((or (string-match-p
+                          "\\(?:^\\|,\\)mathescape\\(?:=true\\)?\\(?:,\\|$\\)"
+                          (car opt))
+                         (string= "mathescape" (car opt)))
+                     'yes)))
+                  (and
+                   (string= (car opt) "mathescape")
+                   (cond
+                    ((or (and (stringp (cdr opt)) (string= (cdr opt) "true"))
+                         (equal '("true") (cdr opt)))
+                     'yes)
+                    ((or (and (stringp (cdr opt)) (string= "false" (cdr opt)))
+                         (equal '("false") (cdr opt)))
+                     'no)))))
+            opts))))
+    (if-let ((mathescape (or (funcall mathescape-status default-options)
+                             (funcall mathescape-status options))))
+        (when (eq mathescape 'yes)
+          (or engrave-faces-latex-mathescape t)))))
+
 (defun org-latex-src--engrave-code (content lang &optional theme options inline)
   "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result.
 When the THEME symbol is non-nil, that theme will be used.
@@ -3464,7 +3498,7 @@ (cl-defun org-latex-src-block--engraved
              (when (and num-start (not (assoc "linenos" engraved-options)))
                `(("linenos")
                  ("firstnumber" ,(number-to-string (1+ num-start)))))
-             (and local-options (list local-options)))))
+             (and local-options `((,local-options))))))
          (engraved-theme (plist-get attributes :engraved-theme))
          (content
           (let* ((code-info (org-export-unravel-code src-block))
@@ -3487,10 +3521,12 @@ (cl-defun org-latex-src-block--engraved
                           (format "(%s)" ref)))))
              nil (and retain-labels (cdr code-info)))))
          (body
-          (org-latex-src--engrave-code
-           content lang
-           (when engraved-theme (intern engraved-theme))
-           options)))
+          (let ((engrave-faces-latex-mathescape
+                 (org-latex-src--engrave-mathescape-p info options)))
+            (org-latex-src--engrave-code
+             content lang
+             (when engraved-theme (intern engraved-theme))
+             options))))
     (concat (car float-env) body (cdr float-env))))
 
 (cl-defun org-latex-src-block--listings
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #13: 0012-news-and-manual-Mention-ox-latex-s-engraved-code.patch --]
[-- Type: text/x-patch, Size: 4727 bytes --]

From a57baf2c0f863aba49264875fd93d62a602ec0d9 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Thu, 12 May 2022 00:03:11 +0800
Subject: [PATCH 12/13] news and manual: Mention ox-latex's engraved code

* etc/ORG-NEWS: Mention the addition of the "engraved" source block
transcoding backend.

* doc/org-manual.org (Footnotes, LaTeX specific properties, Source
blocks in LaTeX export): Basic documentation on the "engraved" source
block transcoding backend.
---
 doc/org-manual.org | 25 ++++++++++++++++---------
 etc/ORG-NEWS       |  9 +++++++++
 2 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index 60bded419..7cba5f18d 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -13811,22 +13811,26 @@ *** Source blocks in LaTeX export
 
 #+vindex: org-latex-listings-options
 #+vindex: org-latex-minted-options
+#+vindex: org-latex-engraved-options
 The LaTeX export back-end passes string values in =:options= to LaTeX
 packages for customization of that specific source block.  In the
-example below, the =:options= are set for Minted.  Minted is a source
-code highlighting LaTeX package with many configurable options[fn:134].
+example below, the =:options= are set for Engraved or Minted.  Minted
+is a source code highlighting LaTeX package with many configurable
+options[fn:134].  Both Minted and Engraved are built on [[https://www.ctan.org/pkg/fvextra][fvextra]], and
+so support many of the same options.
 
 #+begin_example
-,#+ATTR_LATEX: :options commentstyle=\bfseries
+,#+ATTR_LATEX: :options mathescape
 ,#+BEGIN_SRC emacs-lisp
-  (defun Fib (n)
+  (defun Fib (n) ; $n_i = n_{i-2} + n_{i-1}$
     (if (< n 2) n (+ (Fib (- n 1)) (Fib (- n 2)))))
 ,#+END_SRC
 #+end_example
 
-To apply similar configuration options for all source blocks in
-a file, use the ~org-latex-listings-options~ and
-~org-latex-minted-options~ variables.
+To apply similar configuration options for all source blocks in a
+file, use the ~org-latex-listings-options~,
+~org-latex-engraved-options~, and ~org-latex-minted-options~
+variables.
 
 *** Example blocks in LaTeX export
 :PROPERTIES:
@@ -16289,6 +16293,9 @@ **** LaTeX specific properties
 | ~:latex-default-table-environment~     | ~org-latex-default-table-environment~     |
 | ~:latex-default-table-mode~            | ~org-latex-default-table-mode~            |
 | ~:latex-diary-timestamp-format~        | ~org-latex-diary-timestamp-format~        |
+| ~:latex-engraved-options~              | ~org-latex-engraved-options~              |
+| ~:latex-engraved-preamble~             | ~org-latex-engraved-preamble~             |
+| ~:latex-engraved-theme~                | ~org-latex-engraved-theme~                |
 | ~:latex-footnote-defined-format~       | ~org-latex-footnote-defined-format~       |
 | ~:latex-footnote-separator~            | ~org-latex-footnote-separator~            |
 | ~:latex-format-drawer-function~        | ~org-latex-format-drawer-function~        |
@@ -22255,8 +22262,8 @@ * Footnotes
 [fn:114] This works automatically for the HTML backend (it requires
 version 1.34 of the =htmlize.el= package, which you need to install).
 Fontified code chunks in LaTeX can be achieved using either the
-[[https://www.ctan.org/pkg/listings][listings]] package or the [[https://www.ctan.org/pkg/minted][minted]] package.  Refer to
-~org-latex-src-block-backend~ for details.
+[[https://www.ctan.org/pkg/listings][listings]] LaTeX package, [[https://www.ctan.org/pkg/minted][minted]] LaTeX package, or by using
+[[https://elpa.gnu.org/packages/engrave-faces.html][engrave-faces]] .  Refer to ~org-latex-src-block-backend~ for details.
 
 [fn:115] Source code in code blocks may also be evaluated either
 interactively or on export.  See [[*Working with Source Code]] for more
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index ebb3cd649..582816534 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -180,6 +180,15 @@ commands.
 =:noweb-prefix= can be set to =no= to prevent the prefix characters
 from being repeated when expanding a multiline noweb reference.
 
+*** New LaTeX source block backend using =engraved-faces-latex=
+
+When ~org-latex-src-block-backend~ is set to ~engraved~,
+=engrave-faces-latex= from [[http://elpa.gnu.org/packages/engrave-faces.html][engrave-faces]] is used to transcode source
+blocks to LaTeX. This requires the =fvextra=, =float=, and (by
+default, but not necessarily) =tcolorbox= LaTeX packages be
+installed. It uses Emacs' font-lock information, and so tends to
+produce results superior to Minted or Listings.
+
 ** New functions and changes in function arguments
 
 *** New function ~org-element-cache-map~ for quick mapping across Org elements
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #14: 0013-ox-latex-Prefix-lst-to-source-block-labels.patch --]
[-- Type: text/x-patch, Size: 848 bytes --]

From c3851e657611424af10859a2236c0b4e183cc1d7 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 11 May 2022 21:50:36 +0800
Subject: [PATCH 13/13] ox-latex: Prefix lst: to source block labels

* lisp/ox-latex.el (org-latex--label): Use the "lst:" prefix when
generating source block labels ("lst" contracted from "listing").
---
 lisp/ox-latex.el | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 29543f8e9..998f2238d 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1554,6 +1554,7 @@ (defun org-latex--label (datum info &optional force full)
 			   (`paragraph
 			    (and (org-element-property :caption datum)
 				 "fig:"))
+                           (`src-block "lst:")
 			   (_ nil))
 			 (org-export-get-reference datum info))))))
     (cond ((not full) label)
-- 
2.35.3


^ permalink raw reply related	[relevance 2%]

* Re: [PATCH] (v2) New LaTeX code export option: engraved
  @ 2022-05-08 14:30  2%               ` Timothy
  2022-05-11 16:05  2%                 ` [PATCH] (v3) " Timothy
  0 siblings, 1 reply; 200+ results
From: Timothy @ 2022-05-08 14:30 UTC (permalink / raw)
  To: Daniel Fleischer; +Cc: Ihor Radchenko, emacs-orgmode, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 2337 bytes --]

Hi Daniel & co.,

I have a new set of patches (attached), which make use of a major new feature in
engrave-faces v0.3: engraved themes.

Now, the theme used for source blocks can be set by the document keyword
`#+latex_engraved_theme: THEME-NAME'. Furthermore, the theme can be customised on
a per-code-block basis with `#+attr_latex: :engraved-theme THEME-NAME'.

If you try this out, make sure you have the most recent commit of engrave-faces
(531ea687e, soon to be released in v0.3.1).

I’ve also fixed the “Bug: Percentage in caption (even escaped) does not work in
LaTeX export” that Max raised
(<https://list.orgmode.org/YT2PR01MB45101E27DC6251D8F8B7B366F6EC9@YT2PR01MB4510.CANPRD01.PROD.OUTLOOK.COM>).

Daniel Fleischer <danflscr@gmail.com> writes:

> Very nice set of patches, it looks good.

Glad to hear you’ve been able to have a look over the patches. With the feedback
I’ve received here so far, if no issues come up in the next few days I’m
inclined to merge this, add documentation, and see what feedback pops up.

> I must admit it’s not clear how to customize faces since engrave is a bridge
> between major modes choices and latex but maybe show one or two examples (say
> elisp and python) of how to change/override some face.

Sure. The result should be visually identical to what you’d see in elisp/python
buffer, but possibly with a different theme.

Say you wanted to use a tweaked version of the default theme, this could be
accomplished like so:
┌────
│ (setq default2 (alist-get 'default engrave-faces-themes))
│ ;; Make comments hot pink
│ (plist-put (alist-get 'font-lock-comment-face default2) :foreground "#ff69b4")
│ ;; Any other customisations...
│ (add-to-list 'engrave-faces-themes (cons 'default2 default2))
└────

Then in the Org file you can use the “default2” engraved theme with
`#+latex_engraved_theme: default2'.

Let me know if there are any other examples you’d like to see.

> I think next we should apply these patches and be open to feedback
> about source code latex export using these new changes. I also wish
> there was a bit more documentation, but we can add more with time.
> Maybe some feedback from Nicolas G.?

👍 see my earlier comment on merging.

All the best,
Timothy

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Refactor-org-latex-src-block.patch --]
[-- Type: text/x-patch, Size: 15944 bytes --]

From 18adbd0e1226cf3307090861e09e92bfa9cdfbf1 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 14:35:34 +0800
Subject: [PATCH 01/10] ox-latex: Refactor `org-latex-src-block'

* lisp/ox-latex.el (org-latex-src-block): Extract the per-format logic
from `org-latex-src-block' into new dedicated functions:
+ `org-latex-src-block--verbatim'
+ `org-latex-src-block--custom'
+ `org-latex-src-block--minted'
+ `org-latex-src-block--listings'
This makes `org-latex-src-block' much less monolithic, taking it from
175 lines to 30, and I find also makes it easier to understand.
---
 lisp/ox-latex.el | 339 ++++++++++++++++++++++++++---------------------
 1 file changed, 185 insertions(+), 154 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 841ad48bc..c2f728a1c 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2997,164 +2997,195 @@ (defun org-latex-src-block (src-block _contents info)
 	   (float (plist-get attributes :float))
 	   (listings (plist-get info :latex-listings)))
       (cond
-       ;; Case 1.  No source fontification.
        ((or (not lang) (not listings))
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
-                                (org-export-format-code-default src-block info))))
-          (cond ((string= "multicolumn" float)
-                 (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
-                         (plist-get info :latex-default-figure-position)
-                         (if caption-above-p caption-str "")
-                         verbatim
-                         (if caption-above-p "" caption-str)))
-                (caption (concat
-                          (if caption-above-p caption-str "")
-                          verbatim
-                          (if caption-above-p "" (concat "\n" caption-str))))
-                (t verbatim))))
-       ;; Case 2.  Custom environment.
+        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (custom-env
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (formatted-src (org-export-format-code-default src-block info)))
-          (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
-	      (format "\\begin{%s}\n%s\\end{%s}\n"
-		      custom-env
-		      (concat (and caption-above-p caption-str)
-			      formatted-src
-			      (and (not caption-above-p) caption-str))
-		      custom-env)
-	    (format-spec custom-env
-			 `((?s . ,formatted-src)
-			   (?c . ,caption)
-			   (?f . ,float)
-			   (?l . ,(org-latex--label src-block info))
-			   (?o . ,(or (plist-get attributes :options) "")))))))
-       ;; Case 3.  Use minted package.
+        (org-latex-src-block--custom src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
-	(let* ((caption-str (org-latex--caption/label-string src-block info))
-	       (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
-			      (plist-get info :latex-default-figure-position)))
-	       (float-env
-		(cond
-		 ((string= "multicolumn" float)
-		  (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 (caption
-		  (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 ((string= "t" float)
-		  (concat (format "\\begin{listing}[%s]\n"
-				  placement)
-			  "%s\n\\end{listing}"))
-		 (t "%s")))
-	       (options (plist-get info :latex-minted-options))
-	       (body
-		(format
-		 "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
-		 ;; Options.
-		 (concat
-		  (org-latex--make-option-string
-		   (if (or (not num-start) (assoc "linenos" options))
-		       options
-		     (append
-		      `(("linenos")
-			("firstnumber" ,(number-to-string (1+ num-start))))
-		      options)))
-		  (let ((local-options (plist-get attributes :options)))
-		    (and local-options (concat "," local-options))))
-		 ;; Language.
-		 (or (cadr (assq (intern lang)
-				 (plist-get info :latex-minted-langs)))
-		     (downcase lang))
-		 ;; Source code.
-		 (let* ((code-info (org-export-unravel-code src-block))
-			(max-width
-			 (apply 'max
-				(mapcar 'length
-					(org-split-string (car code-info)
-							  "\n")))))
-		   (org-export-format-code
-		    (car code-info)
-		    (lambda (loc _num ref)
-		      (concat
-		       loc
-		       (when ref
-			 ;; Ensure references are flushed to the right,
-			 ;; separated with 6 spaces from the widest line
-			 ;; of code.
-			 (concat (make-string (+ (- max-width (length loc)) 6)
-					      ?\s)
-				 (format "(%s)" ref)))))
-		    nil (and retain-labels (cdr code-info)))))))
-	  ;; Return value.
-	  (format float-env body)))
-       ;; Case 4.  Use listings package.
+        (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (t
-	(let ((lst-lang
-	       (or (cadr (assq (intern lang)
-			       (plist-get info :latex-listings-langs)))
-		   lang))
-	      (caption-str
-	       (when caption
-		 (let ((main (org-export-get-caption src-block))
-		       (secondary (org-export-get-caption src-block t)))
-		   (if (not secondary)
-		       (format "{%s}" (org-export-data main info))
-		     (format "{[%s]%s}"
-			     (org-export-data secondary info)
-			     (org-export-data main info))))))
-	      (lst-opt (plist-get info :latex-listings-options)))
-	  (concat
-	   ;; Options.
-	   (format
-	    "\\lstset{%s}\n"
-	    (concat
-	     (org-latex--make-option-string
-	      (append
-	       lst-opt
-	       (cond
-		((and (not float) (plist-member attributes :float)) nil)
-		((string= "multicolumn" float) '(("float" "*")))
-		((and float (not (assoc "float" lst-opt)))
-		 `(("float" ,(plist-get info :latex-default-figure-position)))))
-	       `(("language" ,lst-lang))
-	       (if label
-		   `(("label" ,(org-latex--label src-block info)))
-		 '(("label" " ")))
-	       (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
-	       `(("captionpos" ,(if caption-above-p "t" "b")))
-	       (cond ((assoc "numbers" lst-opt) nil)
-		     ((not num-start) '(("numbers" "none")))
-		     (t `(("firstnumber" ,(number-to-string (1+ num-start)))
-			  ("numbers" "left"))))))
-	     (let ((local-options (plist-get attributes :options)))
-	       (and local-options (concat "," local-options)))))
-	   ;; Source code.
-	   (format
-	    "\\begin{lstlisting}\n%s\\end{lstlisting}"
-	    (let* ((code-info (org-export-unravel-code src-block))
-		   (max-width
-		    (apply 'max
-			   (mapcar 'length
-				   (org-split-string (car code-info) "\n")))))
-	      (org-export-format-code
-	       (car code-info)
-	       (lambda (loc _num ref)
-		 (concat
-		  loc
-		  (when ref
-		    ;; Ensure references are flushed to the right,
-		    ;; separated with 6 spaces from the widest line of
-		    ;; code
-		    (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
-			    (format "(%s)" ref)))))
-	       nil (and retain-labels (cdr code-info))))))))))))
-
+        (org-latex-src-block--listings src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))))))
+
+(defun org-latex-src-block--verbatim
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels _attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
+                          (org-export-format-code-default src-block info))))
+    (cond ((string= "multicolumn" float)
+           (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
+                   (plist-get info :latex-default-figure-position)
+                   (if caption-above-p caption-str "")
+                   verbatim
+                   (if caption-above-p "" caption-str)))
+          (caption (concat
+                    (if caption-above-p caption-str "")
+                    verbatim
+                    (if caption-above-p "" (concat "\n" caption-str))))
+          (t verbatim))))
+
+(defun org-latex-src-block--custom
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels attributes float custom-env)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (formatted-src (org-export-format-code-default src-block info)))
+    (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
+        (format "\\begin{%s}\n%s\\end{%s}\n"
+                custom-env
+                (concat (and caption-above-p caption-str)
+                        formatted-src
+                        (and (not caption-above-p) caption-str))
+                custom-env)
+      (format-spec custom-env
+                   `((?s . ,formatted-src)
+                     (?c . ,caption)
+                     (?f . ,float)
+                     (?l . ,(org-latex--label src-block info))
+                     (?o . ,(or (plist-get attributes :options) "")))))))
+
+(defun org-latex-src-block--minted
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-minted-options))
+         (body
+          (format
+           "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (if (or (not num-start) (assoc "linenos" options))
+                 options
+               (append
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start))))
+                options)))
+            (let ((local-options (plist-get attributes :options)))
+              (and local-options (concat "," local-options))))
+           ;; Language.
+           (or (cadr (assq (intern lang)
+                           (plist-get info :latex-minted-langs)))
+               (downcase lang))
+           ;; Source code.
+           (let* ((code-info (org-export-unravel-code src-block))
+                  (max-width
+                   (apply 'max
+                          (mapcar 'length
+                                  (org-split-string (car code-info)
+                                                    "\n")))))
+             (org-export-format-code
+              (car code-info)
+              (lambda (loc _num ref)
+                (concat
+                 loc
+                 (when ref
+                   ;; Ensure references are flushed to the right,
+                   ;; separated with 6 spaces from the widest line
+                   ;; of code.
+                   (concat (make-string (+ (- max-width (length loc)) 6)
+                                        ?\s)
+                           (format "(%s)" ref)))))
+              nil (and retain-labels (cdr code-info)))))))
+    ;; Return value.
+    (format float-env body)))
+
+(defun org-latex-src-block--listings
+    (src-block info lang caption caption-above-p label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((lst-lang
+         (or (cadr (assq (intern lang)
+                         (plist-get info :latex-listings-langs)))
+             lang))
+        (caption-str
+         (when caption
+           (let ((main (org-export-get-caption src-block))
+                 (secondary (org-export-get-caption src-block t)))
+             (if (not secondary)
+                 (format "{%s}" (org-export-data main info))
+               (format "{[%s]%s}"
+                       (org-export-data secondary info)
+                       (org-export-data main info))))))
+        (lst-opt (plist-get info :latex-listings-options)))
+    (concat
+     ;; Options.
+     (format
+      "\\lstset{%s}\n"
+      (concat
+       (org-latex--make-option-string
+        (append
+         lst-opt
+         (cond
+          ((and (not float) (plist-member attributes :float)) nil)
+          ((string= "multicolumn" float) '(("float" "*")))
+          ((and float (not (assoc "float" lst-opt)))
+           `(("float" ,(plist-get info :latex-default-figure-position)))))
+         `(("language" ,lst-lang))
+         (if label
+             `(("label" ,(org-latex--label src-block info)))
+           '(("label" " ")))
+         (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
+         `(("captionpos" ,(if caption-above-p "t" "b")))
+         (cond ((assoc "numbers" lst-opt) nil)
+               ((not num-start) '(("numbers" "none")))
+               (t `(("firstnumber" ,(number-to-string (1+ num-start)))
+                    ("numbers" "left"))))))
+       (let ((local-options (plist-get attributes :options)))
+         (and local-options (concat "," local-options)))))
+     ;; Source code.
+     (format
+      "\\begin{lstlisting}\n%s\\end{lstlisting}"
+      (let* ((code-info (org-export-unravel-code src-block))
+             (max-width
+              (apply 'max
+                     (mapcar 'length
+                             (org-split-string (car code-info) "\n")))))
+        (org-export-format-code
+         (car code-info)
+         (lambda (loc _num ref)
+           (concat
+            loc
+            (when ref
+              ;; Ensure references are flushed to the right,
+              ;; separated with 6 spaces from the widest line of
+              ;; code
+              (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
+                      (format "(%s)" ref)))))
+         nil (and retain-labels (cdr code-info))))))))
 
 ;;;; Statistics Cookie
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-ox-latex-Refactor-org-latex-inline-src-block.patch --]
[-- Type: text/x-patch, Size: 4018 bytes --]

From 6635b72356192c3b0be500984b327d0b4ebd8e2b Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 18:53:10 +0800
Subject: [PATCH 02/10] ox-latex: Refactor `org-latex-inline-src-block'

* lisp/ox-latex.el (org-latex-inline-src-block,
org-latex-inline-src-block--minted,
org-latex-inline-src-block--listings): Extract the minted and listings
specific logic out of `org-latex-inline-src-block` into the new
functions `org-latex-inline-src-block--minted` and
`org-latex-inline-src-block--listings`.
---
 lisp/ox-latex.el | 62 +++++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index c2f728a1c..38f36a1f3 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2127,36 +2127,38 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
   "Transcode an INLINE-SRC-BLOCK element from Org to LaTeX.
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
-  (let* ((code (org-element-property :value inline-src-block))
-	 (separator (org-latex--find-verb-separator code)))
-    (cl-case (plist-get info :latex-listings)
-      ;; Do not use a special package: transcode it verbatim, as code.
-      ((nil) (org-latex--text-markup code 'code info))
-      ;; Use minted package.
-      (minted
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (mint-lang (or (cadr (assq (intern org-lang)
-					 (plist-get info :latex-minted-langs)))
-			     (downcase org-lang)))
-	      (options (org-latex--make-option-string
-			(plist-get info :latex-minted-options))))
-	 (format "\\mintinline%s{%s}{%s}"
-		 (if (string= options "") "" (format "[%s]" options))
-		 mint-lang
-		 code)))
-      ;; Use listings package.
-      (otherwise
-       ;; Maybe translate language's name.
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (lst-lang (or (cadr (assq (intern org-lang)
-					(plist-get info :latex-listings-langs)))
-			    org-lang))
-	      (options (org-latex--make-option-string
-			(append (plist-get info :latex-listings-options)
-				`(("language" ,lst-lang))))))
-	 (concat (format "\\lstinline[%s]" options)
-		 separator code separator))))))
-
+  (let ((code (org-element-property :value inline-src-block))
+        (lang (org-element-property :language inline-src-block)))
+    (pcase (plist-get info :latex-listings)
+      ('nil (org-latex--text-markup code 'code info))
+      ('minted (org-latex-inline-src-block--minted info code lang))
+      (_ (org-latex-inline-src-block--listings info code lang)))))
+
+(defun org-latex-inline-src-block--minted (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using minted.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let ((mint-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-minted-langs)))
+                       (downcase lang)))
+        (options (org-latex--make-option-string
+                  (plist-get info :latex-minted-options))))
+    (format "\\mintinline%s{%s}{%s}"
+            (if (string= options "") "" (format "[%s]" options))
+            mint-lang
+            code)))
+
+(defun org-latex-inline-src-block--listings (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let* ((lst-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-listings-langs)))
+                       lang))
+         (separator (org-latex--find-verb-separator code))
+         (options (org-latex--make-option-string
+                   (append (plist-get info :latex-listings-options)
+                           `(("language" ,lst-lang))))))
+    (concat (format "\\lstinline[%s]" options)
+            separator code separator)))
 
 ;;;; Inlinetask
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-ox-latex-More-versitile-option-construction.patch --]
[-- Type: text/x-patch, Size: 4118 bytes --]

From 108f321a80de89c72974fc25fcde36c85023daca Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 23:31:59 +0800
Subject: [PATCH 03/10] ox-latex: More versitile option construction

* lisp/ox-latex.el (org-latex--make-option-string): Support a custom
option seperator string.

(org-latex--make-option-string, org-latex-minted-options,
org-latex-listings-options): The first line of the docstrings for
`org-latex-minted-options` and `org-latex-listings-options` describe the
variables as "association lists", yet `org-latex--make-option-string`
does not handle association lists and an example of two-value lists is
provided.  To make the behaviour match the docstring,
`org-latex--make-option-string` is modified to work with either a list
two-value lists or an association list, and the examples in
`org-latex-minted-options` and `org-latex-listings-options` updated
accordingly.
---
 lisp/ox-latex.el | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 38f36a1f3..2d4b3bace 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1006,12 +1006,16 @@ (defcustom org-latex-listings-options nil
 
 These options are supplied as a comma-separated list to the
 \\lstset command.  Each element of the association list should be
-a list containing two strings: the name of the option, and the
-value.  For example,
+a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-listings-options
     \\='((\"basicstyle\" \"\\\\small\")
       (\"keywordstyle\" \"\\\\color{black}\\\\bfseries\\\\underbar\")))
+  ; or
+  (setq org-latex-listings-options
+    \\='((\"basicstyle\" . \"\\\\small\")
+      (\"keywordstyle\" . \"\\\\color{black}\\\\bfseries\\\\underbar\")))
 
 will typeset the code in a small size font with underlined, bold
 black keywords.
@@ -1059,11 +1063,14 @@ (defcustom org-latex-minted-options nil
 
 These options are supplied within square brackets in
 \\begin{minted} environments.  Each element of the alist should
-be a list containing two strings: the name of the option, and the
-value.  For example,
+be a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-minted-options
     \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-minted-options
+    \\='((\"bgcolor\" . \"bg\") (\"frame\" . \"lines\")))
 
 will result in source blocks being exported with
 
@@ -1506,21 +1513,24 @@ (defun org-latex--find-verb-separator (s)
 	     when (not (string-match (regexp-quote (char-to-string c)) s))
 	     return (char-to-string c))))
 
-(defun org-latex--make-option-string (options)
+(defun org-latex--make-option-string (options &optional seperator)
   "Return a comma separated string of keywords and values.
 OPTIONS is an alist where the key is the options keyword as
 a string, and the value a list containing the keyword value, or
 nil."
   (mapconcat (lambda (pair)
-	       (pcase-let ((`(,keyword ,value) pair))
-		 (concat keyword
-			 (and (> (length value) 0)
-			      (concat "="
-                                      (if (string-match-p (rx (any "[]")) value)
-                                          (format "{%s}" value)
-                                        value))))))
-	     options
-	     ","))
+               (let ((keyword (car pair))
+                     (value (pcase (cdr pair)
+                              ((pred stringp) (cdr pair))
+                              ((pred consp) (cadr pair)))))
+                 (concat keyword
+                         (when value
+                           (concat "="
+                                   (if (string-match-p (rx (any "[]")) value)
+                                       (format "{%s}" value)
+                                     value))))))
+             options
+             (or seperator ",")))
 
 (defun org-latex--wrap-label (element output info)
   "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-ox-latex-Introduce-engraved-code-highlighting.patch --]
[-- Type: text/x-patch, Size: 18190 bytes --]

From 6f2edb89ff4dd5ce7d6618fc13fa83cbeb028e7b Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 20:04:12 +0800
Subject: [PATCH 04/10] ox-latex: Introduce "engraved" code highlighting

* lisp/ox-latex.el (org-latex-src-block, org-latex-src-block--engraved,
org-latex-inline-src-block, org-latex-inline-src-block--engraved,
org-latex-src--engrave-code, org-latex-template, org-latex-listings):
Make use of the engraved-faces package (available on ELPA) to provide an
alternative LaTeX code highlighting backend which functions similarly to
htmlize.el for HTML exports.

(org-latex-engraved-preamble, org-latex-engraved-options): Introduce
variables to construct the preamble for engraved code blocks.

* lisp/ox-beamer.el (org-beamer-template): Modify to add engrave-faces
preamble when applicable.
---
 lisp/ox-beamer.el |  11 ++
 lisp/ox-latex.el  | 294 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 296 insertions(+), 9 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 6be73c91e..4d40f6a1d 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -857,6 +857,17 @@ (defun org-beamer-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity
+                        info t))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity
+                  info t)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 2d4b3bace..1f4d4007d 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -37,6 +37,8 @@ (defvar org-latex-default-packages-alist)
 (defvar org-latex-packages-alist)
 (defvar orgtbl-exp-regexp)
 
+(declare-function engrave-faces-latex-gen-preamble "ext:engrave-faces-latex")
+(declare-function engrave-faces-latex-buffer "ext:engrave-faces-latex")
 
 \f
 ;;; Define Back-End
@@ -125,6 +127,8 @@ (org-export-define-backend 'latex
     (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
     (:latex-default-table-mode nil nil org-latex-default-table-mode)
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
+    (:latex-engraved-options nil nil org-latex-engraved-options)
+    (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -937,22 +941,48 @@ (defcustom org-latex-listings nil
   "Non-nil means export source code using the listings package.
 
 This package will fontify source code, possibly even with color.
-If you want to use this, you also need to make LaTeX use the
-listings package, and if you want to have color, the color
-package.  Just add these to `org-latex-packages-alist', for
-example using customize, or with something like:
+There are four implementations of this functionality you may
+choose from (ordered from least to most capable):
+1. Verbatim (nil)
+2. Listings (t)
+3. Minted (minted)
+4. Engraved (engraved)
+
+The first two options provide basic syntax
+highlighting (listings), or none at all (verbatim).
+
+When using listings, you also need to make use of the LaTeX
+\"listings\" package. The \"color\" package is also needed if you
+would like color too.  These can simply be added to
+`org-latex-packages-alist', using customise or something like:
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\"))
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\"))
 
-Alternatively,
+There are two further options for more comprehensive
+fontification. The first can be set with,
+
+  (setq org-latex-listings \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the engrave-faces
+package (availible from ELPA), and the fvextra LaTeX package be
+installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the tcolorbox LaTeX package in
+addition to fvextra.
+
+The second more comprehensive option can be set with,
 
   (setq org-latex-listings \\='minted)
 
-causes source code to be exported using the minted package as
-opposed to listings.  If you want to use minted, you need to add
-the minted package to `org-latex-packages-alist', for example
+which causes source code to be exported using the minted package
+as opposed to listings.  If you want to use minted, you need to
+add the minted package to `org-latex-packages-alist', for example
 using customize, or with
 
   (require \\='ox-latex)
@@ -971,8 +1001,9 @@ (defcustom org-latex-listings nil
   :type '(choice
 	  (const :tag "Use listings" t)
 	  (const :tag "Use minted" minted)
+	  (const :tag "Use engrave-faces-latex" engraved)
 	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted))))
+  :safe (lambda (s) (memq s '(t nil minted engraved))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1142,6 +1173,148 @@ (defcustom org-latex-custom-lang-environments nil
   :version "26.1"
   :package-version '(Org . "9.0"))
 
+(defcustom org-latex-engraved-preamble
+  "\\usepackage{fvextra}
+
+[FVEXTRA-SETUP]
+
+% Make line numbers smaller and grey.
+\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
+
+\\usepackage{xcolor}
+
+% In case engrave-faces-latex-gen-preamble has not been run.
+\\providecolor{EfD}{HTML}{f7f7f7}
+\\providecolor{EFD}{HTML}{28292e}
+
+% Define a Code environment to prettily wrap the fontified code.
+\\usepackage[breakable,xparse]{tcolorbox}
+\\DeclareTColorBox[]{Code}{o}%
+{colback=EfD!98!EFD, colframe=EfD!95!EFD,
+  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
+  colupper=EFD,
+  IfNoValueTF={#1}%
+  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
+    boxrule=0.5pt, left=2pt}%
+  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
+    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
+  right=2pt, top=1pt, bottom=0.5pt,
+  breakable}
+
+[LISTINGS-SETUP]"
+  "Preamble content injected when using engrave-faces-latex for source blocks.
+This is relevant when `org-latex-listings' is set to `engraved'.
+
+There is quite a lot of flexibility in what this preamble can be,
+as long as it:
+- Loads the fvextra package.
+- Loads the package xcolor (if it is not already loaded elsewhere).
+- Defines a \"Code\" environment (note the capital C), which all
+  \"Verbatim\" environments (provided by fvextra) will be wrapped with.
+
+In the default value the color \"EFD\" is provided as this is the
+foreground colour provided by engrave-faces-latex.  When there
+are example/fixed-width blocks only, the engraved generated
+preamble is not included, and so it is provided so we may use it
+anyway.
+
+Within this preamble there are two recognised macro-like placeholders:
+
+  [FVEXTRA-SETUP]
+
+  [LISTINGS-SETUP]
+
+FVEXTRA-SETUP sets fvextra's defaults according to
+`org-latex-engraved-options', and LISTINGS-SETUP creates the
+listings environment and defines \\listoflistings."
+  :group 'org-export-latex
+  :type 'string
+  :package-version '(Org . "9.6"))
+
+(defcustom org-latex-engraved-options
+  '(("commandchars" . "\\\\\\{\\}")
+    ("highlightcolor" . "white!95!black!80!blue")
+    ("breaklines" . "true")
+    ("breaksymbol" . "\\color{white!60!black}\\tiny\\ensuremath{\\hookrightarrow}"))
+  "Association list of options for the latex fvextra package when engraving code.
+
+These options are set using \\fvset{...} in the preamble of the
+LaTeX export.  Each element of the alist should be a list or cons
+cell containing two strings: the name of the option, and the
+value.  For example,
+
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" \"green\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" . \"green\") (\"frame\" . \"lines\")))
+
+will result in the following LaTeX in the preamble
+
+\\fvset{%
+  bgcolor=bg,
+  frame=lines}
+
+This will affect all fvextra environments.  Note that the same
+options will be applied to all blocks.  If you need
+block-specific options, you may use the following syntax:
+
+  #+ATTR_LATEX: :options key1=value1,key2=value2
+  #+BEGIN_SRC <LANG>
+  ...
+  #+END_SRC"
+  :group 'org-export-latex
+  :type '(alist :key-type (string :tag "option")
+                :value-type (string :tag "value")))
+
+(defun org-latex-generate-engraved-preamble (info syntax-colours-p)
+  "Generate the preamble to setup engraved code.
+The result is constructed from the :latex-engraved-preamble and
+:latex-engraved-optionsn export options, the default values of
+which are given by `org-latex-engraved-preamble' and
+`org-latex-engraved-options' respectively."
+  (let* ((engraved-options
+          (plist-get info :latex-engraved-options))
+         (engraved-preamble (plist-get info :latex-engraved-preamble)))
+    (when (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?" engraved-preamble)
+      (setq engraved-preamble
+            (replace-match
+             (concat
+              "\\fvset{%\n  "
+              (org-latex--make-option-string engraved-options ",\n  ")
+              "}\n")
+             t t
+             engraved-preamble)))
+    (when (string-match "^[ \t]*\\[LISTINGS-SETUP\\][ \t]*\n?" engraved-preamble)
+      (setq engraved-preamble
+            (replace-match
+             (format
+              "%% Support listings with captions
+\\usepackage{float}
+\\floatstyle{%s}
+\\newfloat{listing}{htbp}{lst}
+\\newcommand{\\listingsname}{Listing}
+\\floatname{listing}{\\listingsname}
+\\newcommand{\\listoflistingsname}{List of Listings}
+\\providecommand{\\listoflistings}{\\listof{listing}{\\listoflistingsname}}\n"
+              (if (memq 'src-block org-latex-caption-above)
+                  "plaintop" "plain"))
+             t t
+             engraved-preamble)))
+    (if syntax-colours-p
+        (concat
+         "\n% Setup for code blocks [1/2]\n\n"
+         engraved-preamble
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         (if (require 'engrave-faces-latex nil t)
+             (engrave-faces-latex-gen-preamble)
+           (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
+           "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
+         "\n")
+      (concat
+       "\n% Setup for code blocks\n\n"
+       engraved-preamble
+       "\n"))))
 
 ;;;; Compilation
 
@@ -1756,6 +1929,17 @@ (defun org-latex-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
             (format-spec template spec)))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity
+                        info t))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity
+                  info t)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
@@ -2142,6 +2326,7 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
     (pcase (plist-get info :latex-listings)
       ('nil (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
+      ('engraved (org-latex-inline-src-block--engraved info code lang))
       (_ (org-latex-inline-src-block--listings info code lang)))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
@@ -2157,6 +2342,11 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
+(defun org-latex-inline-src-block--engraved (_info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (format "\\Verb{%s}" (org-latex-src--engrave-code code lang)))
+
 (defun org-latex-inline-src-block--listings (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
@@ -2323,6 +2513,7 @@ (defun org-latex-keyword (keyword _contents info)
 	  (cl-case (plist-get info :latex-listings)
 	    ((nil) "\\listoffigures")
 	    (minted "\\listoflistings")
+	    (engraved "\\listoflistings")
 	    (otherwise "\\lstlistoflistings")))))))))
 
 
@@ -3017,6 +3208,9 @@ (defun org-latex-src-block (src-block _contents info)
                                      num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
         (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float))
+       ((eq listings 'engraved)
+        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
                                        num-start retain-labels attributes float))
        (t
         (org-latex-src-block--listings src-block info lang caption caption-above-p label
@@ -3133,6 +3327,88 @@ (defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
+(defun org-latex-src--engrave-code (content lang)
+  "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result."
+  (if (require 'engrave-faces-latex nil t)
+      (let* ((lang-mode (and lang (org-src-get-lang-mode lang)))
+             (engraved-buffer
+              (with-temp-buffer
+                (insert content)
+                (when lang-mode
+                  (if (functionp lang-mode)
+                      (funcall lang-mode)
+                    (message "Cannot engrave code as %s. %s is undefined."
+                             lang lang-mode)))
+                (engrave-faces-latex-buffer)))
+             (engraved-code
+              (with-current-buffer engraved-buffer
+                (buffer-string))))
+        (kill-buffer engraved-buffer)
+        engraved-code)
+    (user-error "Cannot engrave code as `engrave-faces-latex' is unavailible.")))
+
+(defun org-latex-src-block--engraved
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-engraved-options))
+         (content
+          (let* ((code-info (org-export-unravel-code src-block))
+                 (max-width
+                  (apply 'max
+                         (mapcar 'string-width
+                                 (org-split-string (car code-info)
+                                                   "\n")))))
+            (org-export-format-code
+             (car code-info)
+             (lambda (loc _num ref)
+               (concat
+                loc
+                (when ref
+                  ;; Ensure references are flushed to the right,
+                  ;; separated with 6 spaces from the widest line
+                  ;; of code.
+                  (concat (make-string (+ (- max-width (length loc)) 6)
+                                       ?\s)
+                          (format "(%s)" ref)))))
+             nil (and retain-labels (cdr code-info)))))
+         (body
+          (format
+           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (append
+              (when (and num-start (not (assoc "linenos" options)))
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start)))))
+              (let ((local-options (plist-get attributes :options)))
+                (and local-options (list local-options))))))
+           (org-latex-src--engrave-code content lang))))
+    (format float-env body)))
+
 (defun org-latex-src-block--listings
     (src-block info lang caption caption-above-p label
                num-start retain-labels attributes float)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-ox-latex-Don-t-use-length-to-get-string-width.patch --]
[-- Type: text/x-patch, Size: 1539 bytes --]

From 27a83b36b77e267feb3267d6a4dffd16fdf1d5a7 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 13:59:13 +0800
Subject: [PATCH 05/10] ox-latex: Don't use `length' to get string width

* lisp/ox-latex.el (org-latex-src-block--listings,
org-latex-src-block--engraved, org-latex-src-block--minted): Use
`string-width' instead of `length' to gauge the displayed width of the
string in LaTeX.  This may not be a perfect match, but it should be an
improvement.
---
 lisp/ox-latex.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 1f4d4007d..13ba6cd8c 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3308,7 +3308,7 @@ (defun org-latex-src-block--minted
            (let* ((code-info (org-export-unravel-code src-block))
                   (max-width
                    (apply 'max
-                          (mapcar 'length
+                          (mapcar 'string-width
                                   (org-split-string (car code-info)
                                                     "\n")))))
              (org-export-format-code
@@ -3460,7 +3460,7 @@ (defun org-latex-src-block--listings
       (let* ((code-info (org-export-unravel-code src-block))
              (max-width
               (apply 'max
-                     (mapcar 'length
+                     (mapcar 'string-width
                              (org-split-string (car code-info) "\n")))))
         (org-export-format-code
          (car code-info)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: 0006-ox-latex-Refactor-source-block-transcode-fun-sigs.patch --]
[-- Type: text/x-patch, Size: 7299 bytes --]

From ce7b8d8d1eafa6f2e6d0e247661000fc5272a24c Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 14:02:44 +0800
Subject: [PATCH 06/10] ox-latex: Refactor source block transcode fun sigs

* lisp/ox-latex.el (org-latex-src-block--listings,
org-latex-src-block--engraved, org-latex-src-block--minted,
org-latex-src-block--custom): Refactor these --backend functions to use
cl-defun with keys instead of having an 11-argument signature.
(org-latex-src-block): Adjust for the change in signature of the
--backend functions, and refactor the `cond' statement to use `pcase'.
---
 lisp/ox-latex.el | 82 +++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 43 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 13ba6cd8c..4421bb8f5 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3188,37 +3188,37 @@ (defun org-latex-src-block (src-block _contents info)
 contextual information."
   (when (org-string-nw-p (org-element-property :value src-block))
     (let* ((lang (org-element-property :language src-block))
-	   (caption (org-element-property :caption src-block))
-	   (caption-above-p (org-latex--caption-above-p src-block info))
-	   (label (org-element-property :name src-block))
-	   (custom-env (and lang
-			    (cadr (assq (intern lang)
-					org-latex-custom-lang-environments))))
-	   (num-start (org-export-get-loc src-block info))
-	   (retain-labels (org-element-property :retain-labels src-block))
-	   (attributes (org-export-read-attribute :attr_latex src-block))
-	   (float (plist-get attributes :float))
-	   (listings (plist-get info :latex-listings)))
-      (cond
-       ((or (not lang) (not listings))
-        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))
-       (custom-env
-        (org-latex-src-block--custom src-block info lang caption caption-above-p label
-                                     num-start retain-labels attributes float custom-env))
-       ((eq listings 'minted)
-        (org-latex-src-block--minted src-block info lang caption caption-above-p label
-                                     num-start retain-labels attributes float))
-       ((eq listings 'engraved)
-        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))
-       (t
-        (org-latex-src-block--listings src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))))))
-
-(defun org-latex-src-block--verbatim
-    (src-block info _lang caption caption-above-p _label
-               _num-start _retain-labels _attributes float)
+           (caption (org-element-property :caption src-block))
+           (caption-above-p (org-latex--caption-above-p src-block info))
+           (label (org-element-property :name src-block))
+           (custom-env (and lang
+                            (cadr (assq (intern lang)
+                                        org-latex-custom-lang-environments))))
+           (num-start (org-export-get-loc src-block info))
+           (retain-labels (org-element-property :retain-labels src-block))
+           (attributes (org-export-read-attribute :attr_latex src-block))
+           (float (plist-get attributes :float))
+           (listings (plist-get info :latex-listings)))
+      (funcall
+       (pcase listings
+         ((or (pred not) (guard (not lang))) #'org-latex-src-block--verbatim)
+         ((guard custom-env) #'org-latex-src-block--custom)
+         ('minted #'org-latex-src-block--minted)
+         ('engraved #'org-latex-src-block--engraved)
+         (_ #'org-latex-src-block--listings))
+       :src-block src-block
+       :info info
+       :lang lang
+       :caption caption
+       :caption-above-p caption-above-p
+       :label label
+       :num-start num-start
+       :retain-labels retain-labels
+       :attributes attributes
+       :float float))))
+
+(cl-defun org-latex-src-block--verbatim
+    (&key src-block info caption caption-above-p float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3237,9 +3237,8 @@ (defun org-latex-src-block--verbatim
                     (if caption-above-p "" (concat "\n" caption-str))))
           (t verbatim))))
 
-(defun org-latex-src-block--custom
-    (src-block info _lang caption caption-above-p _label
-               _num-start _retain-labels attributes float custom-env)
+(cl-defun org-latex-src-block--custom
+    (&key src-block info caption caption-above-p attributes float custom-env &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3259,9 +3258,8 @@ (defun org-latex-src-block--custom
                      (?l . ,(org-latex--label src-block info))
                      (?o . ,(or (plist-get attributes :options) "")))))))
 
-(defun org-latex-src-block--minted
-    (src-block info lang caption caption-above-p _label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--minted
+    (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3347,9 +3345,8 @@ (defun org-latex-src--engrave-code (content lang)
         engraved-code)
     (user-error "Cannot engrave code as `engrave-faces-latex' is unavailible.")))
 
-(defun org-latex-src-block--engraved
-    (src-block info lang caption caption-above-p _label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--engraved
+    (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3409,9 +3406,8 @@ (defun org-latex-src-block--engraved
            (org-latex-src--engrave-code content lang))))
     (format float-env body)))
 
-(defun org-latex-src-block--listings
-    (src-block info lang caption caption-above-p label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--listings
+    (&key src-block info lang caption caption-above-p label num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #8: 0007-ox-latex-Replace-org-latex-listings.patch --]
[-- Type: text/x-patch, Size: 16058 bytes --]

From 17e91e6816eeeed398a7f2779108e499729005c8 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 14:46:28 +0800
Subject: [PATCH 07/10] ox-latex: Replace `org-latex-listings'

* lisp/ox-latex.el (org-latex-src-block, org-latex-keyword,
org-latex-inline-src-block, org-latex-template,
org-latex--caption/label-string, org-latex-engraved-preamble,
org-latex-listings): Replace `org-latex-listings' with
`org-latex-src-block-backend', which now can be set to listings/verbatim
and no longer advertises t/nil as valid values.

* lisp/ox-beamer.el (org-beamer-template): Update in the same manner as
`org-latex-template'.

* lisp/org-compat.el: Make `org-latex-listings' an obsolete alias for
`org-latex-src-block-backend'.

* testing/lisp/test-ox.el: Replace `org-latex-listings' reference with
`org-latex-src-block-backend'.

* doc/org-manual.org (Footnotes, LaTeX specific properties, Literal
Examples): Replace references to `org-latex-listings' with
`org-latex-src-block-backend'.

* etc/ORG-NEWS: Add a news entry noting this change.

The variable `org-latex-listings' originally indicated whether source
blocks should use the listings LaTeX package, or not.  This usage has
evolved over the years, and now it sets one of four different
fontification backends.  This renaming should make the variable name a
bit less misleading.
---
 doc/org-manual.org      |   6 +--
 etc/ORG-NEWS            |   9 ++++
 lisp/org-compat.el      |   2 +
 lisp/ox-beamer.el       |   2 +-
 lisp/ox-latex.el        | 111 ++++++++++++++++++++++------------------
 testing/lisp/test-ox.el |   2 +-
 6 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index c0d38cd8c..60bded419 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -11159,7 +11159,7 @@ ** Literal Examples
 #+end_example
 
 #+cindex: formatting source code, markup rules
-#+vindex: org-latex-listings
+#+vindex: org-latex-src-block-backend
 If the example is source code from a programming language, or any
 other text that can be marked up by Font Lock in Emacs, you can ask
 for the example to look like the fontified Emacs buffer[fn:114].  This
@@ -16304,12 +16304,12 @@ **** LaTeX specific properties
 | ~:latex-link-with-unknown-path-format~ | ~org-latex-link-with-unknown-path-format~ |
 | ~:latex-listings-langs~                | ~org-latex-listings-langs~                |
 | ~:latex-listings-options~              | ~org-latex-listings-options~              |
-| ~:latex-listings~                      | ~org-latex-listings~                      |
 | ~:latex-minted-langs~                  | ~org-latex-minted-langs~                  |
 | ~:latex-minted-options~                | ~org-latex-minted-options~                |
 | ~:latex-prefer-user-labels~            | ~org-latex-prefer-user-labels~            |
 | ~:latex-subtitle-format~               | ~org-latex-subtitle-format~               |
 | ~:latex-subtitle-separate~             | ~org-latex-subtitle-separate~             |
+| ~:latex-src-block-backend~             | ~org-latex-src-block-backend~             |
 | ~:latex-table-scientific-notation~     | ~org-latex-table-scientific-notation~     |
 | ~:latex-tables-booktabs~               | ~org-latex-tables-booktabs~               |
 | ~:latex-tables-centered~               | ~org-latex-tables-centered~               |
@@ -22256,7 +22256,7 @@ * Footnotes
 version 1.34 of the =htmlize.el= package, which you need to install).
 Fontified code chunks in LaTeX can be achieved using either the
 [[https://www.ctan.org/pkg/listings][listings]] package or the [[https://www.ctan.org/pkg/minted][minted]] package.  Refer to
-~org-latex-listings~ for details.
+~org-latex-src-block-backend~ for details.
 
 [fn:115] Source code in code blocks may also be evaluated either
 interactively or on export.  See [[*Working with Source Code]] for more
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 27de6da62..ebb3cd649 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -273,6 +273,15 @@ Chmod-style permissions are based on the new variable
 ~org-babel-tangle-default-file-mode~.
 
 *** A new custom setting =org-agenda-clock-report-header= to add a header to org agenda clock report
+
+*** ~org-latex-listings~ has been replaced with ~org-latex-src-block-backend~
+
+~org-latex-listings~ has been renamed to better reflect the current
+purpose of the variable.  The replacement variable
+~org-latex-src-block-backend~ acts in exactly the same way, however it
+accepts =listings= and =verbatim= in place of =t= and =nil= (which
+still work, but are no longer listed as valid options).
+
 * Version 9.5
 
 ** Important announcements and breaking changes
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index a29f206a4..704197645 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -324,6 +324,8 @@ (define-obsolete-variable-alias 'org-latex-create-formula-image-program
   'org-preview-latex-default-process "9.0")
 (define-obsolete-variable-alias 'org-latex-preview-ltxpng-directory
   'org-preview-latex-image-directory "9.0")
+(define-obsolete-variable-alias 'org-latex-listings
+  'org-latex-src-block-backend "9.6")
 (define-obsolete-function-alias 'org-table-p 'org-at-table-p "9.0")
 (define-obsolete-function-alias 'org-on-heading-p 'org-at-heading-p "9.0")
 (define-obsolete-function-alias 'org-at-regexp-p 'org-in-regexp "8.3")
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 4d40f6a1d..3baa4e26e 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -858,7 +858,7 @@ (defun org-beamer-template (contents info)
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
      ;; engrave-faces-latex preamble
-     (when (eq org-latex-listings 'engraved)
+     (when (eq org-latex-src-block-backend 'engraved)
        (let ((src-p (org-element-map (plist-get info :parse-tree)
                         '(src-block inline-src-block) #'identity
                         info t))
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 4421bb8f5..cc6ac291a 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -143,7 +143,7 @@ (org-export-define-backend 'latex
     (:latex-inactive-timestamp-format nil nil org-latex-inactive-timestamp-format)
     (:latex-inline-image-rules nil nil org-latex-inline-image-rules)
     (:latex-link-with-unknown-path-format nil nil org-latex-link-with-unknown-path-format)
-    (:latex-listings nil nil org-latex-listings)
+    (:latex-src-block-backend nil nil org-latex-src-block-backend)
     (:latex-listings-langs nil nil org-latex-listings-langs)
     (:latex-listings-options nil nil org-latex-listings-options)
     (:latex-minted-langs nil nil org-latex-minted-langs)
@@ -937,22 +937,22 @@ (defcustom org-latex-format-inlinetask-function
 
 ;; Src blocks
 
-(defcustom org-latex-listings nil
-  "Non-nil means export source code using the listings package.
+(defcustom org-latex-src-block-backend 'verbatim
+  "Backend used to generate source code listings.
 
-This package will fontify source code, possibly even with color.
-There are four implementations of this functionality you may
+This sets the behaviour for fontifying source code, possibly even with
+color.  There are four implementations of this functionality you may
 choose from (ordered from least to most capable):
-1. Verbatim (nil)
-2. Listings (t)
-3. Minted (minted)
-4. Engraved (engraved)
+1. Verbatim
+2. Listings
+3. Minted
+4. Engraved
 
 The first two options provide basic syntax
 highlighting (listings), or none at all (verbatim).
 
-When using listings, you also need to make use of the LaTeX
-\"listings\" package. The \"color\" package is also needed if you
+When using listings, you also need to make use of LaTeX package
+\"listings\"e. The \"color\" LaTeX package is also needed if you
 would like color too.  These can simply be added to
 `org-latex-packages-alist', using customise or something like:
 
@@ -963,27 +963,12 @@ (defcustom org-latex-listings nil
 There are two further options for more comprehensive
 fontification. The first can be set with,
 
-  (setq org-latex-listings \\='engraved)
+  (setq org-latex-src-block-backend \\='minted)
 
-which causes source code to be run through
-`engrave-faces-latex-buffer', which generates colorings using
-Emacs' font-lock information.  This requires the engrave-faces
-package (availible from ELPA), and the fvextra LaTeX package be
-installed.
-
-The styling of the engraved result can customised with
-`org-latex-engraved-preamble' and `org-latex-engraved-options'.
-The default preamble also uses the tcolorbox LaTeX package in
-addition to fvextra.
-
-The second more comprehensive option can be set with,
-
-  (setq org-latex-listings \\='minted)
-
-which causes source code to be exported using the minted package
-as opposed to listings.  If you want to use minted, you need to
-add the minted package to `org-latex-packages-alist', for example
-using customize, or with
+which causes source code to be exported using the LaTeX package
+minted as opposed to listings.  If you want to use minted, you
+need to add the minted package to `org-latex-packages-alist', for
+example using customize, or with
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"newfloat\" \"minted\"))
@@ -996,14 +981,29 @@ (defcustom org-latex-listings nil
 The minted choice has possible repercussions on the preview of
 latex fragments (see `org-preview-latex-fragment').  If you run
 into previewing problems, please consult
-URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'."
+URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'.
+
+The most comprehensive option can be set with,
+
+  (setq org-latex-src-block-backend \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the Emacs package
+engrave-faces (availible from ELPA), and the LaTeX package
+fvextra be installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the LaTeX package tcolorbox in
+addition to fvextra."
   :group 'org-export-latex
   :type '(choice
-	  (const :tag "Use listings" t)
+	  (const :tag "Use listings" listings)
 	  (const :tag "Use minted" minted)
 	  (const :tag "Use engrave-faces-latex" engraved)
-	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted engraved))))
+	  (const :tag "Export verbatim" verbatim))
+  :safe (lambda (s) (memq s '(listings minted engraved verbatim))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1203,7 +1203,7 @@ (defcustom org-latex-engraved-preamble
 
 [LISTINGS-SETUP]"
   "Preamble content injected when using engrave-faces-latex for source blocks.
-This is relevant when `org-latex-listings' is set to `engraved'.
+This is relevant when `org-latex-src-block-backend' is set to `engraved'.
 
 There is quite a lot of flexibility in what this preamble can be,
 as long as it:
@@ -1523,7 +1523,8 @@ (defun org-latex--caption/label-string (element info)
 			    main)
 		       (and (eq type 'src-block)
 			    (not (plist-get attr :float))
-			    (null (plist-get info :latex-listings)))))
+			    (memq (plist-get info :latex-src-block-backend)
+                                  '(verbatim nil)))))
 	 (short (org-export-get-caption element t))
 	 (caption-from-attr-latex (plist-get attr :caption)))
     (cond
@@ -1543,7 +1544,8 @@ (defun org-latex--caption/label-string (element info)
 		      (paragraph "figure")
 		      (image "figure")
 		      (special-block "figure")
-		      (src-block (if (plist-get info :latex-listings)
+		      (src-block (if (not (memq (plist-get info :latex-src-block-backend)
+                                                '(verbatim nil)))
 				     "listing"
 				   "figure"))
 		      (t (symbol-name type*)))
@@ -1930,7 +1932,7 @@ (defun org-latex-template (contents info)
        (and (stringp template)
             (format-spec template spec)))
      ;; engrave-faces-latex preamble
-     (when (eq org-latex-listings 'engraved)
+     (when (eq org-latex-src-block-backend 'engraved)
        (let ((src-p (org-element-map (plist-get info :parse-tree)
                         '(src-block inline-src-block) #'identity
                         info t))
@@ -2323,11 +2325,17 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
 contextual information."
   (let ((code (org-element-property :value inline-src-block))
         (lang (org-element-property :language inline-src-block)))
-    (pcase (plist-get info :latex-listings)
-      ('nil (org-latex--text-markup code 'code info))
+    (pcase (plist-get info :latex-src-block-backend)
+      ('verbatim (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
       ('engraved (org-latex-inline-src-block--engraved info code lang))
-      (_ (org-latex-inline-src-block--listings info code lang)))))
+      ('listings (org-latex-inline-src-block--listings info code lang))
+      (oldval
+       (message "Please update the LaTeX src-block-backend to %s"
+                (if oldval "listings" "verbatim"))
+       (if oldval
+           (org-latex-inline-src-block--listings info code lang)
+         (org-latex--text-markup code 'code info))))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using minted.
@@ -2510,7 +2518,7 @@ (defun org-latex-keyword (keyword _contents info)
 	      (concat depth (and depth "\n") "\\tableofcontents"))))
 	 ((string-match-p "\\<tables\\>" value) "\\listoftables")
 	 ((string-match-p "\\<listings\\>" value)
-	  (cl-case (plist-get info :latex-listings)
+	  (cl-case (plist-get info :latex-src-block-backend)
 	    ((nil) "\\listoffigures")
 	    (minted "\\listoflistings")
 	    (engraved "\\listoflistings")
@@ -3197,15 +3205,20 @@ (defun org-latex-src-block (src-block _contents info)
            (num-start (org-export-get-loc src-block info))
            (retain-labels (org-element-property :retain-labels src-block))
            (attributes (org-export-read-attribute :attr_latex src-block))
-           (float (plist-get attributes :float))
-           (listings (plist-get info :latex-listings)))
+           (float (plist-get attributes :float)))
       (funcall
-       (pcase listings
-         ((or (pred not) (guard (not lang))) #'org-latex-src-block--verbatim)
-         ((guard custom-env) #'org-latex-src-block--custom)
+       (pcase (plist-get info :latex-src-block-backend)
+         ((or 'verbatim (guard (not lang))) #'org-latex-src-block--verbatim)
          ('minted #'org-latex-src-block--minted)
          ('engraved #'org-latex-src-block--engraved)
-         (_ #'org-latex-src-block--listings))
+         ('listings #'org-latex-src-block--listings)
+         ((guard custom-env) #'org-latex-src-block--custom)
+         (oldval
+          (message "Please update the LaTeX src-block-backend to %s"
+                   (if oldval "listings" "verbatim"))
+          (if oldval
+              #'org-latex-src-block--listings
+            #'org-latex-src-block--verbatim)))
        :src-block src-block
        :info info
        :lang lang
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 25e02b258..28f950813 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -3978,7 +3978,7 @@ (ert-deftest test-org-export/latex-src-block-verbatim-caption ()
 \\end{verbatim}
 \\caption{Caption is below, 60\\%s}
 \\end{figure*}"
-	     (let ((org-latex-listings 'minted) ; inactive due to missing lang
+	     (let ((org-latex-src-block-backend 'minted) ; inactive due to missing lang
 		   (org-latex-default-figure-position "tp"))
 	       ;; Namely "multicolumn" value to get just figure environment
 	       ;; looks like a bug.
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #9: 0008-ox-latex-Support-setting-the-engraved-theme.patch --]
[-- Type: text/x-patch, Size: 3181 bytes --]

From 146146df02434f8b224b21293753f260d0d624b2 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 8 May 2022 02:01:34 +0800
Subject: [PATCH 08/10] ox-latex: Support setting the engraved theme

* lisp/ox-latex.el (org-latex-generate-engraved-preamble,
org-latex-engraved-theme): Introduce the new export keyword
LATEX_ENGRAVED_THEME with default value given by
`org-latex-engraved-theme'.  This is used to set the engraved theme used
in org-latex-engraved-theme.

This bumps the minimum required version of engrave-faces from v0.2 to
v0.3.
---
 lisp/ox-latex.el | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index cc6ac291a..21541e9aa 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -129,6 +129,7 @@ (org-export-define-backend 'latex
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
     (:latex-engraved-options nil nil org-latex-engraved-options)
     (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
+    (:latex-engraved-theme "LATEX_ENGRAVED_THEME" nil org-latex-engraved-theme)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -1267,6 +1268,14 @@ (defcustom org-latex-engraved-options
   :type '(alist :key-type (string :tag "option")
                 :value-type (string :tag "value")))
 
+(defcustom org-latex-engraved-theme nil
+  "The theme that should be used for engraved code, when non-nil.
+This can be set to any theme defined in `engrave-faces-themes' or
+loadable by Emacs.  When set to t, the current Emacs theme is
+used."
+  :group 'org-export-latex
+  :type 'symbol)
+
 (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
   "Generate the preamble to setup engraved code.
 The result is constructed from the :latex-engraved-preamble and
@@ -1275,7 +1284,8 @@ (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
 `org-latex-engraved-options' respectively."
   (let* ((engraved-options
           (plist-get info :latex-engraved-options))
-         (engraved-preamble (plist-get info :latex-engraved-preamble)))
+         (engraved-preamble (plist-get info :latex-engraved-preamble))
+         (engraved-theme (plist-get info :latex-engraved-theme)))
     (when (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?" engraved-preamble)
       (setq engraved-preamble
             (replace-match
@@ -1307,7 +1317,8 @@ (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
          engraved-preamble
          "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
          (if (require 'engrave-faces-latex nil t)
-             (engrave-faces-latex-gen-preamble)
+             (engrave-faces-latex-gen-preamble
+              (when engraved-theme (intern engraved-theme)))
            (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
            "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
          "\n")
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #10: 0009-ox-latex-Support-setting-engraved-theme-per-block.patch --]
[-- Type: text/x-patch, Size: 8907 bytes --]

From dc4989ccf41f09e7fce08036f89e9274ead4e257 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 8 May 2022 15:28:29 +0800
Subject: [PATCH 09/10] ox-latex: Support setting engraved theme per-block

* lisp/ox-latex.el (org-latex-src-block--engraved,
org-latex-src--engrave-code, org-latex-inline-src-block--engraved,
org-latex-generate-engraved-preamble): Allow for the engraved theme used
to be set on a per-src-block basis with #+attr_latex: :engraved-theme
THEME.  Extra setup code is now generated in
`org-latex-generate-engraved-preamble'.  To facilitate the application
of themes to src blocks, `org-latex-src--engrave-code' now takes on a
larger portion of the transcoding work.
---
 lisp/ox-latex.el | 113 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 89 insertions(+), 24 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 21541e9aa..528243a59 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1285,7 +1285,27 @@ (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
   (let* ((engraved-options
           (plist-get info :latex-engraved-options))
          (engraved-preamble (plist-get info :latex-engraved-preamble))
-         (engraved-theme (plist-get info :latex-engraved-theme)))
+         (engraved-theme (plist-get info :latex-engraved-theme))
+         (engraved-themes
+          (cl-delete-duplicates
+           (org-element-map
+               (plist-get info :parse-tree)
+               '(src-block inline-src-block)
+             (lambda (src)
+               (plist-get
+                (org-export-read-attribute :attr_latex src)
+                :engraved-theme))
+             info)))
+         (gen-theme-spec
+          (lambda (theme)
+            (if (eq engrave-faces-latex-output-style 'preset)
+                (engrave-faces-latex-gen-preamble (when theme (intern theme)))
+              (engrave-faces-latex-gen-preamble-line
+               'default
+               (alist-get 'default
+                          (if theme
+                              (engrave-faces-get-theme (intern theme))
+                            engrave-faces-current-preset-style)))))))
     (when (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?" engraved-preamble)
       (setq engraved-preamble
             (replace-match
@@ -1315,10 +1335,31 @@ (defun org-latex-generate-engraved-preamble (info syntax-colours-p)
         (concat
          "\n% Setup for code blocks [1/2]\n\n"
          engraved-preamble
-         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n\n"
          (if (require 'engrave-faces-latex nil t)
-             (engrave-faces-latex-gen-preamble
-              (when engraved-theme (intern engraved-theme)))
+             (if engraved-themes
+                 (concat
+                  (mapconcat
+                   (lambda (theme)
+                     (format
+                      "\n\\newcommand{\\engravedtheme%s}{%%\n%s\n}"
+                      (replace-regexp-in-string "[^A-Za-z]" "" theme)
+                      (replace-regexp-in-string
+                       "newcommand" "renewcommand"
+                       (replace-regexp-in-string
+                        "#" "##"
+                        (funcall gen-theme-spec theme)))))
+                   engraved-themes
+                   "\n")
+                  "\n\n"
+                  (cond
+                   ((memq engraved-theme engraved-themes)
+                    (concat "\\engravedtheme"
+                            (replace-regexp-in-string
+                             "[^A-Za-z]" "" engraved-theme)
+                            "\n"))
+                   (t (funcall gen-theme-spec engraved-theme))))
+               (funcall gen-theme-spec engraved-theme))
            (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
            "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
          "\n")
@@ -2361,10 +2402,11 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
-(defun org-latex-inline-src-block--engraved (_info code lang)
+(defun org-latex-inline-src-block--engraved (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
-  (format "\\Verb{%s}" (org-latex-src--engrave-code code lang)))
+  (org-latex-src--engrave-code
+   code lang nil (plist-get info :latex-engraved-options) t))
 
 (defun org-latex-inline-src-block--listings (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
@@ -3349,13 +3391,18 @@ (cl-defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
-(defun org-latex-src--engrave-code (content lang)
-  "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result."
+(defun org-latex-src--engrave-code (content lang &optional theme options inline)
+  "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result.
+When THEME is non-nil, it will be used."
   (if (require 'engrave-faces-latex nil t)
       (let* ((lang-mode (and lang (org-src-get-lang-mode lang)))
+             (engrave-faces-current-preset-style
+              (if theme
+                  (engrave-faces-get-theme theme)
+                engrave-faces-current-preset-style))
              (engraved-buffer
               (with-temp-buffer
-                (insert content)
+                (insert (string-trim-right content "\n"))
                 (when lang-mode
                   (if (functionp lang-mode)
                       (funcall lang-mode)
@@ -3364,9 +3411,27 @@ (defun org-latex-src--engrave-code (content lang)
                 (engrave-faces-latex-buffer)))
              (engraved-code
               (with-current-buffer engraved-buffer
-                (buffer-string))))
+                (buffer-string)))
+             (engraved-options
+              (when options
+                (concat "["
+                        (if (listp options)
+                            (org-latex--make-option-string options)
+                          options)
+                        "]")))
+             (engraved-wrapped
+              (if inline
+                  (concat "\\Verb" engraved-options "{" engraved-code "}")
+                (concat "\\begin{Code}\\begin{Verbatim}" engraved-options "\n"
+                        engraved-code "\n\\end{Verbatim}\n\\end{Code}"))))
         (kill-buffer engraved-buffer)
-        engraved-code)
+        (if theme
+            (concat "{\\engravedtheme"
+                    (replace-regexp-in-string "[^A-Za-z]" ""
+                                              (symbol-name theme))
+                    engraved-wrapped
+                    "}")
+          engraved-wrapped))
     (user-error "Cannot engrave code as `engrave-faces-latex' is unavailible.")))
 
 (cl-defun org-latex-src-block--engraved
@@ -3394,7 +3459,15 @@ (cl-defun org-latex-src-block--engraved
                             placement)
                     "%s\n\\end{listing}"))
            (t "%s")))
-         (options (plist-get info :latex-engraved-options))
+         (options
+          (let ((engraved-options (plist-get info :latex-engraved-options))
+                (local-options (plist-get attributes :options)))
+            (append
+             (when (and num-start (not (assoc "linenos" engraved-options)))
+               `(("linenos")
+                 ("firstnumber" ,(number-to-string (1+ num-start)))))
+             (and local-options (list local-options)))))
+         (engraved-theme (plist-get attributes :engraved-theme))
          (content
           (let* ((code-info (org-export-unravel-code src-block))
                  (max-width
@@ -3416,18 +3489,10 @@ (cl-defun org-latex-src-block--engraved
                           (format "(%s)" ref)))))
              nil (and retain-labels (cdr code-info)))))
          (body
-          (format
-           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
-           ;; Options.
-           (concat
-            (org-latex--make-option-string
-             (append
-              (when (and num-start (not (assoc "linenos" options)))
-                `(("linenos")
-                  ("firstnumber" ,(number-to-string (1+ num-start)))))
-              (let ((local-options (plist-get attributes :options)))
-                (and local-options (list local-options))))))
-           (org-latex-src--engrave-code content lang))))
+          (org-latex-src--engrave-code
+           content lang
+           (when engraved-theme (intern engraved-theme))
+           options)))
     (format float-env body)))
 
 (cl-defun org-latex-src-block--listings
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #11: 0010-ox-latex-Fix-captions-in-minted-engraved-code.patch --]
[-- Type: text/x-patch, Size: 4986 bytes --]

From ec560f6f037b902d603e9f34bbe593cb4c6bf4a9 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Mon, 9 May 2022 00:04:10 +0800
Subject: [PATCH 10/10] ox-latex: Fix %-captions in minted/engraved code

* lisp/ox-latex.el (org-latex-src-block--engraved,
org-latex-src-block--minted): Refactor float-env to be clearer, and
switch from `format' to `concat' to fix the bug where %-chars in
captions are interpreted as a format specifier.
---
 lisp/ox-latex.el | 55 +++++++++++++++++++++---------------------------
 1 file changed, 24 insertions(+), 31 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 528243a59..bb8072230 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3332,23 +3332,20 @@ (cl-defun org-latex-src-block--minted
   (let* ((caption-str (org-latex--caption/label-string src-block info))
          (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
                         (plist-get info :latex-default-figure-position)))
+         (multicolumn-p (string= "multicolumn" float))
          (float-env
           (cond
-           ((string= "multicolumn" float)
-            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-                    placement
-                    (if caption-above-p caption-str "")
-                    (if caption-above-p "" caption-str)))
-           (caption
-            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-                    placement
-                    (if caption-above-p caption-str "")
-                    (if caption-above-p "" caption-str)))
+           ((or caption multicolumn-p)
+            (cons
+             (concat "\\begin{listing" (when multicolumn-p "*")
+                     "}[" placement "]\n"
+                     (if caption-above-p caption-str ""))
+             (concat "\n" (if caption-above-p "" caption-str)
+                     "\\end{listing" (when multicolumn-p "*") "}")))
            ((string= "t" float)
-            (concat (format "\\begin{listing}[%s]\n"
-                            placement)
-                    "%s\n\\end{listing}"))
-           (t "%s")))
+            (cons
+             (concat "\\begin{listing}[" placement "]\n")
+             "\n\\end{listing}"))))
          (options (plist-get info :latex-minted-options))
          (body
           (format
@@ -3388,8 +3385,7 @@ (cl-defun org-latex-src-block--minted
                                         ?\s)
                            (format "(%s)" ref)))))
               nil (and retain-labels (cdr code-info)))))))
-    ;; Return value.
-    (format float-env body)))
+    (concat (car float-env) body (cdr float-env))))
 
 (defun org-latex-src--engrave-code (content lang &optional theme options inline)
   "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result.
@@ -3442,23 +3438,20 @@ (cl-defun org-latex-src-block--engraved
   (let* ((caption-str (org-latex--caption/label-string src-block info))
          (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
                         (plist-get info :latex-default-figure-position)))
+         (multicolumn-p (string= "multicolumn" float))
          (float-env
           (cond
-           ((string= "multicolumn" float)
-            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-                    placement
-                    (if caption-above-p caption-str "")
-                    (if caption-above-p "" caption-str)))
-           (caption
-            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-                    placement
-                    (if caption-above-p caption-str "")
-                    (if caption-above-p "" caption-str)))
+           ((or caption multicolumn-p)
+            (cons
+             (concat "\\begin{listing" (when multicolumn-p "*")
+                     "}[" placement "]\n"
+                     (if caption-above-p caption-str ""))
+             (concat "\n" (if caption-above-p "" caption-str)
+                     "\\end{listing" (when multicolumn-p "*") "}")))
            ((string= "t" float)
-            (concat (format "\\begin{listing}[%s]\n"
-                            placement)
-                    "%s\n\\end{listing}"))
-           (t "%s")))
+            (cons
+             (concat "\\begin{listing}[" placement "]\n")
+             "\n\\end{listing}"))))
          (options
           (let ((engraved-options (plist-get info :latex-engraved-options))
                 (local-options (plist-get attributes :options)))
@@ -3493,7 +3486,7 @@ (cl-defun org-latex-src-block--engraved
            content lang
            (when engraved-theme (intern engraved-theme))
            options)))
-    (format float-env body)))
+    (concat (car float-env) body (cdr float-env))))
 
 (cl-defun org-latex-src-block--listings
     (&key src-block info lang caption caption-above-p label num-start retain-labels attributes float &allow-other-keys)
-- 
2.35.3


^ permalink raw reply related	[relevance 2%]

* Re: [PATCH] New LaTeX code export option: engraved
  2022-05-07  6:57  3%         ` Timothy
@ 2022-05-07 10:40  3%           ` Timothy
    0 siblings, 1 reply; 200+ results
From: Timothy @ 2022-05-07 10:40 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode, Daniel Fleischer, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 131 bytes --]

Ooops, a paren error managed to slip in there.

Here’s a new set, with a little extra refactoring slipped in.

–
Timothy

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Refactor-org-latex-src-block.patch --]
[-- Type: text/x-patch, Size: 15942 bytes --]

From d231437e2c9f96bf70520d9ddda810a95667fcdd Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 14:35:34 +0800
Subject: [PATCH 1/7] ox-latex: Refactor `org-latex-src-block'

* lisp/ox-latex.el (org-latex-src-block): Extract the per-format logic
from `org-latex-src-block' into new dedicated functions:
+ `org-latex-src-block--verbatim'
+ `org-latex-src-block--custom'
+ `org-latex-src-block--minted'
+ `org-latex-src-block--listings'
This makes `org-latex-src-block' much less monolithic, taking it from
175 lines to 30, and I find also makes it easier to understand.
---
 lisp/ox-latex.el | 339 ++++++++++++++++++++++++++---------------------
 1 file changed, 185 insertions(+), 154 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 841ad48bc..c2f728a1c 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2997,164 +2997,195 @@ (defun org-latex-src-block (src-block _contents info)
 	   (float (plist-get attributes :float))
 	   (listings (plist-get info :latex-listings)))
       (cond
-       ;; Case 1.  No source fontification.
        ((or (not lang) (not listings))
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
-                                (org-export-format-code-default src-block info))))
-          (cond ((string= "multicolumn" float)
-                 (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
-                         (plist-get info :latex-default-figure-position)
-                         (if caption-above-p caption-str "")
-                         verbatim
-                         (if caption-above-p "" caption-str)))
-                (caption (concat
-                          (if caption-above-p caption-str "")
-                          verbatim
-                          (if caption-above-p "" (concat "\n" caption-str))))
-                (t verbatim))))
-       ;; Case 2.  Custom environment.
+        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (custom-env
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (formatted-src (org-export-format-code-default src-block info)))
-          (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
-	      (format "\\begin{%s}\n%s\\end{%s}\n"
-		      custom-env
-		      (concat (and caption-above-p caption-str)
-			      formatted-src
-			      (and (not caption-above-p) caption-str))
-		      custom-env)
-	    (format-spec custom-env
-			 `((?s . ,formatted-src)
-			   (?c . ,caption)
-			   (?f . ,float)
-			   (?l . ,(org-latex--label src-block info))
-			   (?o . ,(or (plist-get attributes :options) "")))))))
-       ;; Case 3.  Use minted package.
+        (org-latex-src-block--custom src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
-	(let* ((caption-str (org-latex--caption/label-string src-block info))
-	       (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
-			      (plist-get info :latex-default-figure-position)))
-	       (float-env
-		(cond
-		 ((string= "multicolumn" float)
-		  (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 (caption
-		  (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 ((string= "t" float)
-		  (concat (format "\\begin{listing}[%s]\n"
-				  placement)
-			  "%s\n\\end{listing}"))
-		 (t "%s")))
-	       (options (plist-get info :latex-minted-options))
-	       (body
-		(format
-		 "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
-		 ;; Options.
-		 (concat
-		  (org-latex--make-option-string
-		   (if (or (not num-start) (assoc "linenos" options))
-		       options
-		     (append
-		      `(("linenos")
-			("firstnumber" ,(number-to-string (1+ num-start))))
-		      options)))
-		  (let ((local-options (plist-get attributes :options)))
-		    (and local-options (concat "," local-options))))
-		 ;; Language.
-		 (or (cadr (assq (intern lang)
-				 (plist-get info :latex-minted-langs)))
-		     (downcase lang))
-		 ;; Source code.
-		 (let* ((code-info (org-export-unravel-code src-block))
-			(max-width
-			 (apply 'max
-				(mapcar 'length
-					(org-split-string (car code-info)
-							  "\n")))))
-		   (org-export-format-code
-		    (car code-info)
-		    (lambda (loc _num ref)
-		      (concat
-		       loc
-		       (when ref
-			 ;; Ensure references are flushed to the right,
-			 ;; separated with 6 spaces from the widest line
-			 ;; of code.
-			 (concat (make-string (+ (- max-width (length loc)) 6)
-					      ?\s)
-				 (format "(%s)" ref)))))
-		    nil (and retain-labels (cdr code-info)))))))
-	  ;; Return value.
-	  (format float-env body)))
-       ;; Case 4.  Use listings package.
+        (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (t
-	(let ((lst-lang
-	       (or (cadr (assq (intern lang)
-			       (plist-get info :latex-listings-langs)))
-		   lang))
-	      (caption-str
-	       (when caption
-		 (let ((main (org-export-get-caption src-block))
-		       (secondary (org-export-get-caption src-block t)))
-		   (if (not secondary)
-		       (format "{%s}" (org-export-data main info))
-		     (format "{[%s]%s}"
-			     (org-export-data secondary info)
-			     (org-export-data main info))))))
-	      (lst-opt (plist-get info :latex-listings-options)))
-	  (concat
-	   ;; Options.
-	   (format
-	    "\\lstset{%s}\n"
-	    (concat
-	     (org-latex--make-option-string
-	      (append
-	       lst-opt
-	       (cond
-		((and (not float) (plist-member attributes :float)) nil)
-		((string= "multicolumn" float) '(("float" "*")))
-		((and float (not (assoc "float" lst-opt)))
-		 `(("float" ,(plist-get info :latex-default-figure-position)))))
-	       `(("language" ,lst-lang))
-	       (if label
-		   `(("label" ,(org-latex--label src-block info)))
-		 '(("label" " ")))
-	       (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
-	       `(("captionpos" ,(if caption-above-p "t" "b")))
-	       (cond ((assoc "numbers" lst-opt) nil)
-		     ((not num-start) '(("numbers" "none")))
-		     (t `(("firstnumber" ,(number-to-string (1+ num-start)))
-			  ("numbers" "left"))))))
-	     (let ((local-options (plist-get attributes :options)))
-	       (and local-options (concat "," local-options)))))
-	   ;; Source code.
-	   (format
-	    "\\begin{lstlisting}\n%s\\end{lstlisting}"
-	    (let* ((code-info (org-export-unravel-code src-block))
-		   (max-width
-		    (apply 'max
-			   (mapcar 'length
-				   (org-split-string (car code-info) "\n")))))
-	      (org-export-format-code
-	       (car code-info)
-	       (lambda (loc _num ref)
-		 (concat
-		  loc
-		  (when ref
-		    ;; Ensure references are flushed to the right,
-		    ;; separated with 6 spaces from the widest line of
-		    ;; code
-		    (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
-			    (format "(%s)" ref)))))
-	       nil (and retain-labels (cdr code-info))))))))))))
-
+        (org-latex-src-block--listings src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))))))
+
+(defun org-latex-src-block--verbatim
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels _attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
+                          (org-export-format-code-default src-block info))))
+    (cond ((string= "multicolumn" float)
+           (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
+                   (plist-get info :latex-default-figure-position)
+                   (if caption-above-p caption-str "")
+                   verbatim
+                   (if caption-above-p "" caption-str)))
+          (caption (concat
+                    (if caption-above-p caption-str "")
+                    verbatim
+                    (if caption-above-p "" (concat "\n" caption-str))))
+          (t verbatim))))
+
+(defun org-latex-src-block--custom
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels attributes float custom-env)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (formatted-src (org-export-format-code-default src-block info)))
+    (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
+        (format "\\begin{%s}\n%s\\end{%s}\n"
+                custom-env
+                (concat (and caption-above-p caption-str)
+                        formatted-src
+                        (and (not caption-above-p) caption-str))
+                custom-env)
+      (format-spec custom-env
+                   `((?s . ,formatted-src)
+                     (?c . ,caption)
+                     (?f . ,float)
+                     (?l . ,(org-latex--label src-block info))
+                     (?o . ,(or (plist-get attributes :options) "")))))))
+
+(defun org-latex-src-block--minted
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-minted-options))
+         (body
+          (format
+           "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (if (or (not num-start) (assoc "linenos" options))
+                 options
+               (append
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start))))
+                options)))
+            (let ((local-options (plist-get attributes :options)))
+              (and local-options (concat "," local-options))))
+           ;; Language.
+           (or (cadr (assq (intern lang)
+                           (plist-get info :latex-minted-langs)))
+               (downcase lang))
+           ;; Source code.
+           (let* ((code-info (org-export-unravel-code src-block))
+                  (max-width
+                   (apply 'max
+                          (mapcar 'length
+                                  (org-split-string (car code-info)
+                                                    "\n")))))
+             (org-export-format-code
+              (car code-info)
+              (lambda (loc _num ref)
+                (concat
+                 loc
+                 (when ref
+                   ;; Ensure references are flushed to the right,
+                   ;; separated with 6 spaces from the widest line
+                   ;; of code.
+                   (concat (make-string (+ (- max-width (length loc)) 6)
+                                        ?\s)
+                           (format "(%s)" ref)))))
+              nil (and retain-labels (cdr code-info)))))))
+    ;; Return value.
+    (format float-env body)))
+
+(defun org-latex-src-block--listings
+    (src-block info lang caption caption-above-p label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((lst-lang
+         (or (cadr (assq (intern lang)
+                         (plist-get info :latex-listings-langs)))
+             lang))
+        (caption-str
+         (when caption
+           (let ((main (org-export-get-caption src-block))
+                 (secondary (org-export-get-caption src-block t)))
+             (if (not secondary)
+                 (format "{%s}" (org-export-data main info))
+               (format "{[%s]%s}"
+                       (org-export-data secondary info)
+                       (org-export-data main info))))))
+        (lst-opt (plist-get info :latex-listings-options)))
+    (concat
+     ;; Options.
+     (format
+      "\\lstset{%s}\n"
+      (concat
+       (org-latex--make-option-string
+        (append
+         lst-opt
+         (cond
+          ((and (not float) (plist-member attributes :float)) nil)
+          ((string= "multicolumn" float) '(("float" "*")))
+          ((and float (not (assoc "float" lst-opt)))
+           `(("float" ,(plist-get info :latex-default-figure-position)))))
+         `(("language" ,lst-lang))
+         (if label
+             `(("label" ,(org-latex--label src-block info)))
+           '(("label" " ")))
+         (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
+         `(("captionpos" ,(if caption-above-p "t" "b")))
+         (cond ((assoc "numbers" lst-opt) nil)
+               ((not num-start) '(("numbers" "none")))
+               (t `(("firstnumber" ,(number-to-string (1+ num-start)))
+                    ("numbers" "left"))))))
+       (let ((local-options (plist-get attributes :options)))
+         (and local-options (concat "," local-options)))))
+     ;; Source code.
+     (format
+      "\\begin{lstlisting}\n%s\\end{lstlisting}"
+      (let* ((code-info (org-export-unravel-code src-block))
+             (max-width
+              (apply 'max
+                     (mapcar 'length
+                             (org-split-string (car code-info) "\n")))))
+        (org-export-format-code
+         (car code-info)
+         (lambda (loc _num ref)
+           (concat
+            loc
+            (when ref
+              ;; Ensure references are flushed to the right,
+              ;; separated with 6 spaces from the widest line of
+              ;; code
+              (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
+                      (format "(%s)" ref)))))
+         nil (and retain-labels (cdr code-info))))))))
 
 ;;;; Statistics Cookie
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-ox-latex-Refactor-org-latex-inline-src-block.patch --]
[-- Type: text/x-patch, Size: 4016 bytes --]

From aa8406ce64507b870322495e8f9b54317930ed24 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 18:53:10 +0800
Subject: [PATCH 2/7] ox-latex: Refactor `org-latex-inline-src-block'

* lisp/ox-latex.el (org-latex-inline-src-block,
org-latex-inline-src-block--minted,
org-latex-inline-src-block--listings): Extract the minted and listings
specific logic out of `org-latex-inline-src-block` into the new
functions `org-latex-inline-src-block--minted` and
`org-latex-inline-src-block--listings`.
---
 lisp/ox-latex.el | 62 +++++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index c2f728a1c..38f36a1f3 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2127,36 +2127,38 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
   "Transcode an INLINE-SRC-BLOCK element from Org to LaTeX.
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
-  (let* ((code (org-element-property :value inline-src-block))
-	 (separator (org-latex--find-verb-separator code)))
-    (cl-case (plist-get info :latex-listings)
-      ;; Do not use a special package: transcode it verbatim, as code.
-      ((nil) (org-latex--text-markup code 'code info))
-      ;; Use minted package.
-      (minted
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (mint-lang (or (cadr (assq (intern org-lang)
-					 (plist-get info :latex-minted-langs)))
-			     (downcase org-lang)))
-	      (options (org-latex--make-option-string
-			(plist-get info :latex-minted-options))))
-	 (format "\\mintinline%s{%s}{%s}"
-		 (if (string= options "") "" (format "[%s]" options))
-		 mint-lang
-		 code)))
-      ;; Use listings package.
-      (otherwise
-       ;; Maybe translate language's name.
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (lst-lang (or (cadr (assq (intern org-lang)
-					(plist-get info :latex-listings-langs)))
-			    org-lang))
-	      (options (org-latex--make-option-string
-			(append (plist-get info :latex-listings-options)
-				`(("language" ,lst-lang))))))
-	 (concat (format "\\lstinline[%s]" options)
-		 separator code separator))))))
-
+  (let ((code (org-element-property :value inline-src-block))
+        (lang (org-element-property :language inline-src-block)))
+    (pcase (plist-get info :latex-listings)
+      ('nil (org-latex--text-markup code 'code info))
+      ('minted (org-latex-inline-src-block--minted info code lang))
+      (_ (org-latex-inline-src-block--listings info code lang)))))
+
+(defun org-latex-inline-src-block--minted (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using minted.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let ((mint-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-minted-langs)))
+                       (downcase lang)))
+        (options (org-latex--make-option-string
+                  (plist-get info :latex-minted-options))))
+    (format "\\mintinline%s{%s}{%s}"
+            (if (string= options "") "" (format "[%s]" options))
+            mint-lang
+            code)))
+
+(defun org-latex-inline-src-block--listings (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let* ((lst-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-listings-langs)))
+                       lang))
+         (separator (org-latex--find-verb-separator code))
+         (options (org-latex--make-option-string
+                   (append (plist-get info :latex-listings-options)
+                           `(("language" ,lst-lang))))))
+    (concat (format "\\lstinline[%s]" options)
+            separator code separator)))
 
 ;;;; Inlinetask
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-ox-latex-More-versitile-option-construction.patch --]
[-- Type: text/x-patch, Size: 4116 bytes --]

From 62d6703f0dd622916dff8aab960db6df4cb58cf7 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 23:31:59 +0800
Subject: [PATCH 3/7] ox-latex: More versitile option construction

* lisp/ox-latex.el (org-latex--make-option-string): Support a custom
option seperator string.

(org-latex--make-option-string, org-latex-minted-options,
org-latex-listings-options): The first line of the docstrings for
`org-latex-minted-options` and `org-latex-listings-options` describe the
variables as "association lists", yet `org-latex--make-option-string`
does not handle association lists and an example of two-value lists is
provided.  To make the behaviour match the docstring,
`org-latex--make-option-string` is modified to work with either a list
two-value lists or an association list, and the examples in
`org-latex-minted-options` and `org-latex-listings-options` updated
accordingly.
---
 lisp/ox-latex.el | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 38f36a1f3..2d4b3bace 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1006,12 +1006,16 @@ (defcustom org-latex-listings-options nil
 
 These options are supplied as a comma-separated list to the
 \\lstset command.  Each element of the association list should be
-a list containing two strings: the name of the option, and the
-value.  For example,
+a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-listings-options
     \\='((\"basicstyle\" \"\\\\small\")
       (\"keywordstyle\" \"\\\\color{black}\\\\bfseries\\\\underbar\")))
+  ; or
+  (setq org-latex-listings-options
+    \\='((\"basicstyle\" . \"\\\\small\")
+      (\"keywordstyle\" . \"\\\\color{black}\\\\bfseries\\\\underbar\")))
 
 will typeset the code in a small size font with underlined, bold
 black keywords.
@@ -1059,11 +1063,14 @@ (defcustom org-latex-minted-options nil
 
 These options are supplied within square brackets in
 \\begin{minted} environments.  Each element of the alist should
-be a list containing two strings: the name of the option, and the
-value.  For example,
+be a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-minted-options
     \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-minted-options
+    \\='((\"bgcolor\" . \"bg\") (\"frame\" . \"lines\")))
 
 will result in source blocks being exported with
 
@@ -1506,21 +1513,24 @@ (defun org-latex--find-verb-separator (s)
 	     when (not (string-match (regexp-quote (char-to-string c)) s))
 	     return (char-to-string c))))
 
-(defun org-latex--make-option-string (options)
+(defun org-latex--make-option-string (options &optional seperator)
   "Return a comma separated string of keywords and values.
 OPTIONS is an alist where the key is the options keyword as
 a string, and the value a list containing the keyword value, or
 nil."
   (mapconcat (lambda (pair)
-	       (pcase-let ((`(,keyword ,value) pair))
-		 (concat keyword
-			 (and (> (length value) 0)
-			      (concat "="
-                                      (if (string-match-p (rx (any "[]")) value)
-                                          (format "{%s}" value)
-                                        value))))))
-	     options
-	     ","))
+               (let ((keyword (car pair))
+                     (value (pcase (cdr pair)
+                              ((pred stringp) (cdr pair))
+                              ((pred consp) (cadr pair)))))
+                 (concat keyword
+                         (when value
+                           (concat "="
+                                   (if (string-match-p (rx (any "[]")) value)
+                                       (format "{%s}" value)
+                                     value))))))
+             options
+             (or seperator ",")))
 
 (defun org-latex--wrap-label (element output info)
   "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-ox-latex-Introduce-engraved-code-highlighting.patch --]
[-- Type: text/x-patch, Size: 17212 bytes --]

From 81155a80fb261812718dcb991fd22f87bb1d5ef6 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 20:04:12 +0800
Subject: [PATCH 4/7] ox-latex: Introduce "engraved" code highlighting

* lisp/ox-latex.el (org-latex-src-block, org-latex-src-block--engraved,
org-latex-inline-src-block, org-latex-inline-src-block--engraved,
org-latex-src--engrave-code, org-latex-template, org-latex-listings):
Make use of the engraved-faces package (available on ELPA) to provide an
alternative LaTeX code highlighting backend which functions similarly to
htmlize.el for HTML exports.

(org-latex-engraved-preamble, org-latex-engraved-options): Introduce
variables to construct the preamble for engraved code blocks.

* lisp/ox-beamer.el (org-beamer-template): Modify to add engrave-faces
preamble when applicable.

tweak
---
 lisp/ox-beamer.el |  11 ++
 lisp/ox-latex.el  | 272 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 274 insertions(+), 9 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 6be73c91e..4d40f6a1d 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -857,6 +857,17 @@ (defun org-beamer-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity
+                        info t))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity
+                  info t)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 2d4b3bace..10cd6d76d 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -37,6 +37,8 @@ (defvar org-latex-default-packages-alist)
 (defvar org-latex-packages-alist)
 (defvar orgtbl-exp-regexp)
 
+(declare-function engrave-faces-latex-gen-preamble "ext:engrave-faces-latex")
+(declare-function engrave-faces-latex-buffer "ext:engrave-faces-latex")
 
 \f
 ;;; Define Back-End
@@ -125,6 +127,8 @@ (org-export-define-backend 'latex
     (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
     (:latex-default-table-mode nil nil org-latex-default-table-mode)
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
+    (:latex-engraved-options nil nil org-latex-engraved-options)
+    (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -937,22 +941,48 @@ (defcustom org-latex-listings nil
   "Non-nil means export source code using the listings package.
 
 This package will fontify source code, possibly even with color.
-If you want to use this, you also need to make LaTeX use the
-listings package, and if you want to have color, the color
-package.  Just add these to `org-latex-packages-alist', for
-example using customize, or with something like:
+There are four implementations of this functionality you may
+choose from (ordered from least to most capable):
+1. Verbatim (nil)
+2. Listings (t)
+3. Minted (minted)
+4. Engraved (engraved)
+
+The first two options provide basic syntax
+highlighting (listings), or none at all (verbatim).
+
+When using listings, you also need to make use of the LaTeX
+\"listings\" package. The \"color\" package is also needed if you
+would like color too.  These can simply be added to
+`org-latex-packages-alist', using customise or something like:
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\"))
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\"))
 
-Alternatively,
+There are two further options for more comprehensive
+fontification. The first can be set with,
+
+  (setq org-latex-listings \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the engrave-faces
+package (availible from ELPA), and the fvextra LaTeX package be
+installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the tcolorbox LaTeX package in
+addition to fvextra.
+
+The second more comprehensive option can be set with,
 
   (setq org-latex-listings \\='minted)
 
-causes source code to be exported using the minted package as
-opposed to listings.  If you want to use minted, you need to add
-the minted package to `org-latex-packages-alist', for example
+which causes source code to be exported using the minted package
+as opposed to listings.  If you want to use minted, you need to
+add the minted package to `org-latex-packages-alist', for example
 using customize, or with
 
   (require \\='ox-latex)
@@ -971,8 +1001,9 @@ (defcustom org-latex-listings nil
   :type '(choice
 	  (const :tag "Use listings" t)
 	  (const :tag "Use minted" minted)
+	  (const :tag "Use engrave-faces-latex" engraved)
 	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted))))
+  :safe (lambda (s) (memq s '(t nil minted engraved))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1142,6 +1173,127 @@ (defcustom org-latex-custom-lang-environments nil
   :version "26.1"
   :package-version '(Org . "9.0"))
 
+(defcustom org-latex-engraved-preamble
+  "\\usepackage{fvextra}
+
+[FVEXTRA-SETUP]
+
+% Make line numbers smaller and grey.
+\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
+
+\\usepackage{xcolor}
+
+\\providecolor{codebackground}{HTML}{f7f7f7}
+\\providecolor{codeborder}{HTML}{f0f0f0}
+\\providecolor{EFD}{HTML}{28292e}
+
+% Define a Code environment to prettily wrap the fontified code.
+\\usepackage[breakable,xparse]{tcolorbox}
+\\DeclareTColorBox[]{Code}{o}%
+{colback=codebackground, colframe=codeborder,
+  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
+  colupper=EFD,
+  IfNoValueTF={#1}%
+  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
+    boxrule=0.5pt, left=2pt}%
+  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
+    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
+  right=2pt, top=1pt, bottom=0.5pt,
+  breakable}"
+  "Preamble content injected when using engrave-faces-latex for source blocks.
+This is relevant when `org-latex-listings' is set to `engraved'.
+
+There is quite a lot of flexibility in what this preamble can be, as long as it:
+- Loads the fvextra package.
+- Loads the package xcolor (if it is not already loader elsewhere).
+- Defines a \"Code\" environment (note the capital C), which all
+  \"Verbatim\" environments (provided by fvextra) will be wrapped with.
+
+A macro-like placeholder is used to set fvextra's defaults according to
+`org-latex-engraved-options':
+
+  [FVEXTRA-SETUP]
+
+In the default value the color \"EFD\" is provided as this is the
+foreground colour provided by engrave-faces-latex.  When there
+are example/fixed-width blocks only, the engraved generated
+preamble is not included, and so it is provided so we may use it
+anyway."
+  :group 'org-export-latex
+  :type 'string
+  :package-version '(Org . "9.6"))
+
+(defcustom org-latex-engraved-options
+  '(("commandchars" . "\\\\\\{\\}")
+    ("highlightcolor" . "white!95!black!80!blue")
+    ("breaklines" . "true")
+    ("breaksymbol" . "\\color{white!60!black}\\tiny\\ensuremath{\\hookrightarrow}"))
+  "Association list of options for the latex fvextra package when engraving code.
+
+These options are set using \\fvset{...} in the preamble of the
+LaTeX export.  Each element of the alist should be a list or cons
+cell containing two strings: the name of the option, and the
+value.  For example,
+
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" \"green\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" . \"green\") (\"frame\" . \"lines\")))
+
+will result in the following LaTeX in the preamble
+
+\\fvset{%
+  bgcolor=bg,
+  frame=lines}
+
+This will affect all fvextra environments.  Note that the same
+options will be applied to all blocks.  If you need
+block-specific options, you may use the following syntax:
+
+  #+ATTR_LATEX: :options key1=value1,key2=value2
+  #+BEGIN_SRC <LANG>
+  ...
+  #+END_SRC"
+  :group 'org-export-latex
+  :type '(alist :key-type (string :tag "option")
+                :value-type (string :tag "value")))
+
+(defun org-latex-generate-engraved-preamble (info syntax-colours-p)
+  "Generate the preamble to setup engraved code.
+The result is constructed from the :latex-engraved-preamble and
+:latex-engraved-optionsn export options, the default values of
+which are given by `org-latex-engraved-preamble' and
+`org-latex-engraved-options' respectively."
+  (let* ((engraved-options
+          (plist-get info :latex-engraved-options))
+         (engraved-preamble-template
+          (plist-get info :latex-engraved-preamble))
+         (engraved-preamble
+          (if (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?"
+                            engraved-preamble-template)
+              (replace-match
+               (concat
+                "\\fvset{%\n  "
+                (org-latex--make-option-string engraved-options ",\n  ")
+                "}\n")
+               t t
+               engraved-preamble-template)
+            engraved-preamble-template)))
+    (if syntax-colours-p
+        (concat
+         "\n% Setup for code blocks [1/2]\n\n"
+         engraved-preamble
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         (if (require 'engrave-faces-latex nil t)
+             (engrave-faces-latex-gen-preamble)
+           (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
+           "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
+         "\n")
+      (concat
+       "\n% Setup for code blocks\n\n"
+       engraved-preamble
+       "\n"))))
 
 ;;;; Compilation
 
@@ -1756,6 +1908,17 @@ (defun org-latex-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
             (format-spec template spec)))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity
+                        info t))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity
+                  info t)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
@@ -2142,6 +2305,7 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
     (pcase (plist-get info :latex-listings)
       ('nil (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
+      ('engraved (org-latex-inline-src-block--engraved info code lang))
       (_ (org-latex-inline-src-block--listings info code lang)))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
@@ -2157,6 +2321,11 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
+(defun org-latex-inline-src-block--engraved (_info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (format "\\Verb{%s}" (org-latex-src--engrave-code code lang)))
+
 (defun org-latex-inline-src-block--listings (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
@@ -3017,6 +3186,9 @@ (defun org-latex-src-block (src-block _contents info)
                                      num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
         (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float))
+       ((eq listings 'engraved)
+        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
                                        num-start retain-labels attributes float))
        (t
         (org-latex-src-block--listings src-block info lang caption caption-above-p label
@@ -3133,6 +3305,88 @@ (defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
+(defun org-latex-src--engrave-code (content lang)
+  "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result."
+  (if (require 'engrave-faces-latex nil t)
+      (let* ((lang-mode (and lang (org-src-get-lang-mode lang)))
+             (engraved-buffer
+              (with-temp-buffer
+                (insert content)
+                (when lang-mode
+                  (if (functionp lang-mode)
+                      (funcall lang-mode)
+                    (message "Cannot engrave code as %s. %s is undefined."
+                             lang lang-mode)))
+                (engrave-faces-latex-buffer)))
+             (engraved-code
+              (with-current-buffer engraved-buffer
+                (buffer-string))))
+        (kill-buffer engraved-buffer)
+        engraved-code)
+    (user-error "Cannot engrave code as `engrave-faces-latex' is unavailible.")))
+
+(defun org-latex-src-block--engraved
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-engraved-options))
+         (content
+          (let* ((code-info (org-export-unravel-code src-block))
+                 (max-width
+                  (apply 'max
+                         (mapcar 'string-width
+                                 (org-split-string (car code-info)
+                                                   "\n")))))
+            (org-export-format-code
+             (car code-info)
+             (lambda (loc _num ref)
+               (concat
+                loc
+                (when ref
+                  ;; Ensure references are flushed to the right,
+                  ;; separated with 6 spaces from the widest line
+                  ;; of code.
+                  (concat (make-string (+ (- max-width (length loc)) 6)
+                                       ?\s)
+                          (format "(%s)" ref)))))
+             nil (and retain-labels (cdr code-info)))))
+         (body
+          (format
+           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (append
+              (when (and num-start (not (assoc "linenos" options)))
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start)))))
+              (let ((local-options (plist-get attributes :options)))
+                (and local-options (list local-options))))))
+           (org-latex-src--engrave-code content lang))))
+    (format float-env body)))
+
 (defun org-latex-src-block--listings
     (src-block info lang caption caption-above-p label
                num-start retain-labels attributes float)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-ox-latex-Don-t-use-length-to-get-string-width.patch --]
[-- Type: text/x-patch, Size: 1537 bytes --]

From 96cf9853329dacd69745a225a889855dd13e5c2c Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 13:59:13 +0800
Subject: [PATCH 5/7] ox-latex: Don't use `length' to get string width

* lisp/ox-latex.el (org-latex-src-block--listings,
org-latex-src-block--engraved, org-latex-src-block--minted): Use
`string-width' instead of `length' to gauge the displayed width of the
string in LaTeX.  This may not be a perfect match, but it should be an
improvement.
---
 lisp/ox-latex.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 10cd6d76d..afd7ee48e 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3286,7 +3286,7 @@ (defun org-latex-src-block--minted
            (let* ((code-info (org-export-unravel-code src-block))
                   (max-width
                    (apply 'max
-                          (mapcar 'length
+                          (mapcar 'string-width
                                   (org-split-string (car code-info)
                                                     "\n")))))
              (org-export-format-code
@@ -3438,7 +3438,7 @@ (defun org-latex-src-block--listings
       (let* ((code-info (org-export-unravel-code src-block))
              (max-width
               (apply 'max
-                     (mapcar 'length
+                     (mapcar 'string-width
                              (org-split-string (car code-info) "\n")))))
         (org-export-format-code
          (car code-info)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: 0006-ox-latex-Refactor-source-block-transcode-fun-sigs.patch --]
[-- Type: text/x-patch, Size: 7297 bytes --]

From f191a03ef97f5f8e29b18b73238ab659709ae230 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 14:02:44 +0800
Subject: [PATCH 6/7] ox-latex: Refactor source block transcode fun sigs

* lisp/ox-latex.el (org-latex-src-block--listings,
org-latex-src-block--engraved, org-latex-src-block--minted,
org-latex-src-block--custom): Refactor these --backend functions to use
cl-defun with keys instead of having an 11-argument signature.
(org-latex-src-block): Adjust for the change in signature of the
--backend functions, and refactor the `cond' statement to use `pcase'.
---
 lisp/ox-latex.el | 82 +++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 43 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index afd7ee48e..9150c1011 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3166,37 +3166,37 @@ (defun org-latex-src-block (src-block _contents info)
 contextual information."
   (when (org-string-nw-p (org-element-property :value src-block))
     (let* ((lang (org-element-property :language src-block))
-	   (caption (org-element-property :caption src-block))
-	   (caption-above-p (org-latex--caption-above-p src-block info))
-	   (label (org-element-property :name src-block))
-	   (custom-env (and lang
-			    (cadr (assq (intern lang)
-					org-latex-custom-lang-environments))))
-	   (num-start (org-export-get-loc src-block info))
-	   (retain-labels (org-element-property :retain-labels src-block))
-	   (attributes (org-export-read-attribute :attr_latex src-block))
-	   (float (plist-get attributes :float))
-	   (listings (plist-get info :latex-listings)))
-      (cond
-       ((or (not lang) (not listings))
-        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))
-       (custom-env
-        (org-latex-src-block--custom src-block info lang caption caption-above-p label
-                                     num-start retain-labels attributes float custom-env))
-       ((eq listings 'minted)
-        (org-latex-src-block--minted src-block info lang caption caption-above-p label
-                                     num-start retain-labels attributes float))
-       ((eq listings 'engraved)
-        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))
-       (t
-        (org-latex-src-block--listings src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))))))
-
-(defun org-latex-src-block--verbatim
-    (src-block info _lang caption caption-above-p _label
-               _num-start _retain-labels _attributes float)
+           (caption (org-element-property :caption src-block))
+           (caption-above-p (org-latex--caption-above-p src-block info))
+           (label (org-element-property :name src-block))
+           (custom-env (and lang
+                            (cadr (assq (intern lang)
+                                        org-latex-custom-lang-environments))))
+           (num-start (org-export-get-loc src-block info))
+           (retain-labels (org-element-property :retain-labels src-block))
+           (attributes (org-export-read-attribute :attr_latex src-block))
+           (float (plist-get attributes :float))
+           (listings (plist-get info :latex-listings)))
+      (funcall
+       (pcase listings
+         ((or (pred not) (guard (not lang))) #'org-latex-src-block--verbatim)
+         ((guard custom-env) #'org-latex-src-block--custom)
+         ('minted #'org-latex-src-block--minted)
+         ('engraved #'org-latex-src-block--engraved)
+         (_ #'org-latex-src-block--listings))
+       :src-block src-block
+       :info info
+       :lang lang
+       :caption caption
+       :caption-above-p caption-above-p
+       :label label
+       :num-start num-start
+       :retain-labels retain-labels
+       :attributes attributes
+       :float float))))
+
+(cl-defun org-latex-src-block--verbatim
+    (&key src-block info caption caption-above-p float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3215,9 +3215,8 @@ (defun org-latex-src-block--verbatim
                     (if caption-above-p "" (concat "\n" caption-str))))
           (t verbatim))))
 
-(defun org-latex-src-block--custom
-    (src-block info _lang caption caption-above-p _label
-               _num-start _retain-labels attributes float custom-env)
+(cl-defun org-latex-src-block--custom
+    (&key src-block info caption caption-above-p attributes float custom-env &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3237,9 +3236,8 @@ (defun org-latex-src-block--custom
                      (?l . ,(org-latex--label src-block info))
                      (?o . ,(or (plist-get attributes :options) "")))))))
 
-(defun org-latex-src-block--minted
-    (src-block info lang caption caption-above-p _label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--minted
+    (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3325,9 +3323,8 @@ (defun org-latex-src--engrave-code (content lang)
         engraved-code)
     (user-error "Cannot engrave code as `engrave-faces-latex' is unavailible.")))
 
-(defun org-latex-src-block--engraved
-    (src-block info lang caption caption-above-p _label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--engraved
+    (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3387,9 +3384,8 @@ (defun org-latex-src-block--engraved
            (org-latex-src--engrave-code content lang))))
     (format float-env body)))
 
-(defun org-latex-src-block--listings
-    (src-block info lang caption caption-above-p label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--listings
+    (&key src-block info lang caption caption-above-p label num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #8: 0007-ox-latex-Replace-org-latex-listings.patch --]
[-- Type: text/x-patch, Size: 16128 bytes --]

From adb4b6df3b4549fd6afd6cfb6ae8945e89882cfc Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 14:46:28 +0800
Subject: [PATCH 7/7] ox-latex: Replace `org-latex-listings'

* lisp/ox-latex.el (org-latex-src-block, org-latex-keyword,
org-latex-inline-src-block, org-latex-template,
org-latex--caption/label-string, org-latex-engraved-preamble,
org-latex-listings): Replace `org-latex-listings' with
`org-latex-src-block-backend', which now can be set to listings/verbatim
and no longer advertises t/nil as valid values.

* lisp/ox-beamer.el (org-beamer-template): Update in the same manner as
`org-latex-template'.

* lisp/org-compat.el: Make `org-latex-listings' an obsolete alias for
`org-latex-src-block-backend'.

* testing/lisp/test-ox.el: Replace `org-latex-listings' reference with
`org-latex-src-block-backend'.

* doc/org-manual.org (Footnotes, LaTeX specific properties, Literal
Examples): Replace references to `org-latex-listings' with
`org-latex-src-block-backend'.

* etc/ORG-NEWS: Add a news entry noting this change.

The variable `org-latex-listings' originally indicated whether source
blocks should use the listings LaTeX package, or not.  This usage has
evolved over the years, and now it sets one of four different
fontification backends.  This renaming should make the variable name a
bit less misleading.
---
 doc/org-manual.org      |   6 +--
 etc/ORG-NEWS            |   9 ++++
 lisp/org-compat.el      |   2 +
 lisp/ox-beamer.el       |   2 +-
 lisp/ox-latex.el        | 111 ++++++++++++++++++++++------------------
 testing/lisp/test-ox.el |   2 +-
 6 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index c0d38cd8c..60bded419 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -11159,7 +11159,7 @@ ** Literal Examples
 #+end_example
 
 #+cindex: formatting source code, markup rules
-#+vindex: org-latex-listings
+#+vindex: org-latex-src-block-backend
 If the example is source code from a programming language, or any
 other text that can be marked up by Font Lock in Emacs, you can ask
 for the example to look like the fontified Emacs buffer[fn:114].  This
@@ -16304,12 +16304,12 @@ **** LaTeX specific properties
 | ~:latex-link-with-unknown-path-format~ | ~org-latex-link-with-unknown-path-format~ |
 | ~:latex-listings-langs~                | ~org-latex-listings-langs~                |
 | ~:latex-listings-options~              | ~org-latex-listings-options~              |
-| ~:latex-listings~                      | ~org-latex-listings~                      |
 | ~:latex-minted-langs~                  | ~org-latex-minted-langs~                  |
 | ~:latex-minted-options~                | ~org-latex-minted-options~                |
 | ~:latex-prefer-user-labels~            | ~org-latex-prefer-user-labels~            |
 | ~:latex-subtitle-format~               | ~org-latex-subtitle-format~               |
 | ~:latex-subtitle-separate~             | ~org-latex-subtitle-separate~             |
+| ~:latex-src-block-backend~             | ~org-latex-src-block-backend~             |
 | ~:latex-table-scientific-notation~     | ~org-latex-table-scientific-notation~     |
 | ~:latex-tables-booktabs~               | ~org-latex-tables-booktabs~               |
 | ~:latex-tables-centered~               | ~org-latex-tables-centered~               |
@@ -22256,7 +22256,7 @@ * Footnotes
 version 1.34 of the =htmlize.el= package, which you need to install).
 Fontified code chunks in LaTeX can be achieved using either the
 [[https://www.ctan.org/pkg/listings][listings]] package or the [[https://www.ctan.org/pkg/minted][minted]] package.  Refer to
-~org-latex-listings~ for details.
+~org-latex-src-block-backend~ for details.
 
 [fn:115] Source code in code blocks may also be evaluated either
 interactively or on export.  See [[*Working with Source Code]] for more
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 1e8558c7b..c5f0bcb33 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -268,6 +268,15 @@ Chmod-style permissions are based on the new variable
 ~org-babel-tangle-default-file-mode~.
 
 *** A new custom setting =org-agenda-clock-report-header= to add a header to org agenda clock report
+
+*** ~org-latex-listings~ has been replaced with ~org-latex-src-block-backend~
+
+~org-latex-listings~ has been renamed to better reflect the current
+purpose of the variable.  The replacement variable
+~org-latex-src-block-backend~ acts in exactly the same way, however it
+accepts =listings= and =verbatim= in place of =t= and =nil= (which
+still work, but are no longer listed as valid options).
+
 * Version 9.5
 
 ** Important announcements and breaking changes
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index f599e246e..c1a78e834 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -324,6 +324,8 @@ (define-obsolete-variable-alias 'org-latex-create-formula-image-program
   'org-preview-latex-default-process "9.0")
 (define-obsolete-variable-alias 'org-latex-preview-ltxpng-directory
   'org-preview-latex-image-directory "9.0")
+(define-obsolete-variable-alias 'org-latex-listings
+  'org-latex-src-block-backend "9.6")
 (define-obsolete-function-alias 'org-table-p 'org-at-table-p "9.0")
 (define-obsolete-function-alias 'org-on-heading-p 'org-at-heading-p "9.0")
 (define-obsolete-function-alias 'org-at-regexp-p 'org-in-regexp "8.3")
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 4d40f6a1d..3baa4e26e 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -858,7 +858,7 @@ (defun org-beamer-template (contents info)
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
      ;; engrave-faces-latex preamble
-     (when (eq org-latex-listings 'engraved)
+     (when (eq org-latex-src-block-backend 'engraved)
        (let ((src-p (org-element-map (plist-get info :parse-tree)
                         '(src-block inline-src-block) #'identity
                         info t))
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 9150c1011..ffa89188b 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -143,7 +143,7 @@ (org-export-define-backend 'latex
     (:latex-inactive-timestamp-format nil nil org-latex-inactive-timestamp-format)
     (:latex-inline-image-rules nil nil org-latex-inline-image-rules)
     (:latex-link-with-unknown-path-format nil nil org-latex-link-with-unknown-path-format)
-    (:latex-listings nil nil org-latex-listings)
+    (:latex-src-block-backend nil nil org-latex-src-block-backend)
     (:latex-listings-langs nil nil org-latex-listings-langs)
     (:latex-listings-options nil nil org-latex-listings-options)
     (:latex-minted-langs nil nil org-latex-minted-langs)
@@ -937,22 +937,22 @@ (defcustom org-latex-format-inlinetask-function
 
 ;; Src blocks
 
-(defcustom org-latex-listings nil
-  "Non-nil means export source code using the listings package.
+(defcustom org-latex-src-block-backend 'verbatim
+  "Backend used to generate source code listings.
 
-This package will fontify source code, possibly even with color.
-There are four implementations of this functionality you may
+This sets the behaviour for fontifying source code, possibly even with
+color.  There are four implementations of this functionality you may
 choose from (ordered from least to most capable):
-1. Verbatim (nil)
-2. Listings (t)
-3. Minted (minted)
-4. Engraved (engraved)
+1. Verbatim
+2. Listings
+3. Minted
+4. Engraved
 
 The first two options provide basic syntax
 highlighting (listings), or none at all (verbatim).
 
-When using listings, you also need to make use of the LaTeX
-\"listings\" package. The \"color\" package is also needed if you
+When using listings, you also need to make use of LaTeX package
+\"listings\"e. The \"color\" LaTeX package is also needed if you
 would like color too.  These can simply be added to
 `org-latex-packages-alist', using customise or something like:
 
@@ -963,27 +963,12 @@ (defcustom org-latex-listings nil
 There are two further options for more comprehensive
 fontification. The first can be set with,
 
-  (setq org-latex-listings \\='engraved)
+  (setq org-latex-src-block-backend \\='minted)
 
-which causes source code to be run through
-`engrave-faces-latex-buffer', which generates colorings using
-Emacs' font-lock information.  This requires the engrave-faces
-package (availible from ELPA), and the fvextra LaTeX package be
-installed.
-
-The styling of the engraved result can customised with
-`org-latex-engraved-preamble' and `org-latex-engraved-options'.
-The default preamble also uses the tcolorbox LaTeX package in
-addition to fvextra.
-
-The second more comprehensive option can be set with,
-
-  (setq org-latex-listings \\='minted)
-
-which causes source code to be exported using the minted package
-as opposed to listings.  If you want to use minted, you need to
-add the minted package to `org-latex-packages-alist', for example
-using customize, or with
+which causes source code to be exported using the LaTeX package
+minted as opposed to listings.  If you want to use minted, you
+need to add the minted package to `org-latex-packages-alist', for
+example using customize, or with
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"newfloat\" \"minted\"))
@@ -996,14 +981,29 @@ (defcustom org-latex-listings nil
 The minted choice has possible repercussions on the preview of
 latex fragments (see `org-preview-latex-fragment').  If you run
 into previewing problems, please consult
-URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'."
+URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'.
+
+The most comprehensive option can be set with,
+
+  (setq org-latex-src-block-backend \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the Emacs package
+engrave-faces (availible from ELPA), and the LaTeX package
+fvextra be installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the LaTeX package tcolorbox in
+addition to fvextra."
   :group 'org-export-latex
   :type '(choice
-	  (const :tag "Use listings" t)
+	  (const :tag "Use listings" listings)
 	  (const :tag "Use minted" minted)
 	  (const :tag "Use engrave-faces-latex" engraved)
-	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted engraved))))
+	  (const :tag "Export verbatim" verbatim))
+  :safe (lambda (s) (memq s '(listings minted engraved verbatim))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1201,7 +1201,7 @@ (defcustom org-latex-engraved-preamble
   right=2pt, top=1pt, bottom=0.5pt,
   breakable}"
   "Preamble content injected when using engrave-faces-latex for source blocks.
-This is relevant when `org-latex-listings' is set to `engraved'.
+This is relevant when `org-latex-src-block-backend' is set to `engraved'.
 
 There is quite a lot of flexibility in what this preamble can be, as long as it:
 - Loads the fvextra package.
@@ -1502,7 +1502,8 @@ (defun org-latex--caption/label-string (element info)
 			    main)
 		       (and (eq type 'src-block)
 			    (not (plist-get attr :float))
-			    (null (plist-get info :latex-listings)))))
+			    (memq (plist-get info :latex-src-block-backend)
+                                  '(verbatim nil)))))
 	 (short (org-export-get-caption element t))
 	 (caption-from-attr-latex (plist-get attr :caption)))
     (cond
@@ -1522,7 +1523,8 @@ (defun org-latex--caption/label-string (element info)
 		      (paragraph "figure")
 		      (image "figure")
 		      (special-block "figure")
-		      (src-block (if (plist-get info :latex-listings)
+		      (src-block (if (not (memq (plist-get info :latex-src-block-backend)
+                                                '(verbatim nil)))
 				     "listing"
 				   "figure"))
 		      (t (symbol-name type*)))
@@ -1909,7 +1911,7 @@ (defun org-latex-template (contents info)
        (and (stringp template)
             (format-spec template spec)))
      ;; engrave-faces-latex preamble
-     (when (eq org-latex-listings 'engraved)
+     (when (eq org-latex-src-block-backend 'engraved)
        (let ((src-p (org-element-map (plist-get info :parse-tree)
                         '(src-block inline-src-block) #'identity
                         info t))
@@ -2302,11 +2304,17 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
 contextual information."
   (let ((code (org-element-property :value inline-src-block))
         (lang (org-element-property :language inline-src-block)))
-    (pcase (plist-get info :latex-listings)
-      ('nil (org-latex--text-markup code 'code info))
+    (pcase (plist-get info :latex-src-block-backend)
+      ('verbatim (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
       ('engraved (org-latex-inline-src-block--engraved info code lang))
-      (_ (org-latex-inline-src-block--listings info code lang)))))
+      ('listings (org-latex-inline-src-block--listings info code lang))
+      (oldval
+       (message "Please update the LaTeX src-block-backend to %s"
+                (if oldval "listings" "verbatim"))
+       (if oldval
+           (org-latex-inline-src-block--listings info code lang)
+         (org-latex--text-markup code 'code info))))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using minted.
@@ -2489,7 +2497,7 @@ (defun org-latex-keyword (keyword _contents info)
 	      (concat depth (and depth "\n") "\\tableofcontents"))))
 	 ((string-match-p "\\<tables\\>" value) "\\listoftables")
 	 ((string-match-p "\\<listings\\>" value)
-	  (cl-case (plist-get info :latex-listings)
+	  (cl-case (plist-get info :latex-src-block-backend)
 	    ((nil) "\\listoffigures")
 	    (minted "\\listoflistings")
 	    (otherwise "\\lstlistoflistings")))))))))
@@ -3175,15 +3183,20 @@ (defun org-latex-src-block (src-block _contents info)
            (num-start (org-export-get-loc src-block info))
            (retain-labels (org-element-property :retain-labels src-block))
            (attributes (org-export-read-attribute :attr_latex src-block))
-           (float (plist-get attributes :float))
-           (listings (plist-get info :latex-listings)))
+           (float (plist-get attributes :float)))
       (funcall
-       (pcase listings
-         ((or (pred not) (guard (not lang))) #'org-latex-src-block--verbatim)
-         ((guard custom-env) #'org-latex-src-block--custom)
+       (pcase (plist-get info :latex-src-block-backend)
+         ((or 'verbatim (guard (not lang))) #'org-latex-src-block--verbatim)
          ('minted #'org-latex-src-block--minted)
          ('engraved #'org-latex-src-block--engraved)
-         (_ #'org-latex-src-block--listings))
+         ('listings #'org-latex-src-block--listings)
+         ((guard custom-env) #'org-latex-src-block--custom)
+         (oldval
+          (message "Please update the LaTeX src-block-backend to %s"
+                   (if oldval "listings" "verbatim"))
+          (if oldval
+              #'org-latex-src-block--listings
+            #'org-latex-src-block--verbatim)))
        :src-block src-block
        :info info
        :lang lang
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 25e02b258..28f950813 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -3978,7 +3978,7 @@ (ert-deftest test-org-export/latex-src-block-verbatim-caption ()
 \\end{verbatim}
 \\caption{Caption is below, 60\\%s}
 \\end{figure*}"
-	     (let ((org-latex-listings 'minted) ; inactive due to missing lang
+	     (let ((org-latex-src-block-backend 'minted) ; inactive due to missing lang
 		   (org-latex-default-figure-position "tp"))
 	       ;; Namely "multicolumn" value to get just figure environment
 	       ;; looks like a bug.
-- 
2.35.3


^ permalink raw reply related	[relevance 3%]

* Re: [PATCH] New LaTeX code export option: engraved
  @ 2022-05-07  6:57  3%         ` Timothy
  2022-05-07 10:40  3%           ` Timothy
  0 siblings, 1 reply; 200+ results
From: Timothy @ 2022-05-07  6:57 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode, Daniel Fleischer, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 3409 bytes --]

Hi Ihor,

Find attached an updated patchset, and comments below :)

Ihor Radchenko <yantar92@gmail.com> writes:

> Maybe “The other two options”? Also, using first/second here is a bit
> confusing because: (1) they are actually 3/4 in the above list; (2)
> engraved is listed last.

Docstring changed.

>> +The second more comprehensive option can be used with,
>
> *can be set with

Changed.

> I feel slightly confused about using the word “package” here. Which one
> refers to LaTeX package and which one to Emacs? I would state “Emacs
> package” explicitly to highlight contrast with “LaTeX package”.

Clarifications added to the docstring.

>> +\\{\\\FancyVerbLine}
>
> I’d like to see a comment on what it does.

Added.

> Same request to provide a comment. Also, what it that % TODO doing
> there? It is confusing.

A comment has been added, and the TODO removed.

> Also, it is unclear what the [breakable,xparse] options to tcolorbox are
> doing there and what will happen if the user removes them.

“breakable” allows the box to be broken across pages, and “xparse” provides
`\DeclareTColorBox'.

> Further, I am wondering what is going to happen if the user happens to
> have tcolorbox without options loaded via org-latex-packages-alist.

They could see: ERROR: LaTeX Error: Option clash for package tcolorbox.

They would need to tweak such a tcolorbox entry to include the options used
here.

>> +There is quite a lot of flexibility in what this preamble can be, as long as it:
>> +- Loads the fvextra package.
>> +- Loads the package xcolor (if it is not already loader elsewhere).
>> +- Defines a \“Code\” environment (note the capital C), which can be
>> +  later used to wrap \“Verbatim\” environments (provided by fvextra).
>
> The last point is not very clear. What kind of environment?

Anything that the user wants to do to modify the display of the generated
`Verbatim' environment.

>> +(defun org-latex-generate-engraved-preamble (info syntax-colours-p)
>> +  “Generate the preamble to setup engraved code.
>> +The result is constructed from `org-latex-engraved-preamble’ and
>> +`org-latex-engraved-options’.”
>
> This is relying on
>
> (:latex-engraved-options nil nil org-latex-engraved-options)
> (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
>
> If it changes any time in future (e.g. to allow per-file settings), the
> docstring may be overlooked.

Docstring tweaked.

> I’d use FIRST-MATCH argument for org-element-map. It will be slightly
> faster on large buffers.

Ah nice, I’ll make use of that.

>> -                       (downcase org-lang)))
>> +                       (downcase lang)))
>
> I am not sure if this belongs to this patch. Please double check.

Ooops, moved to the correct patch.

>> +                            (mapcar ’length
>> +                                    (org-split-string (car code-info)
>> +                                                      “”)))))
>
> I am not sure how well it will work with e.g. Chinese characters in comments.

I’ve added a patch replacing `length' with `string-width'

> Maybe the functions could be rewritten using cl-defun with keys and
> &allow-other-keys and then called via apply on a let-bound arg plist?

Done.

All the best,
Timothy

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Refactor-org-latex-src-block.patch --]
[-- Type: text/x-patch, Size: 15942 bytes --]

From d231437e2c9f96bf70520d9ddda810a95667fcdd Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 14:35:34 +0800
Subject: [PATCH 1/7] ox-latex: Refactor `org-latex-src-block'

* lisp/ox-latex.el (org-latex-src-block): Extract the per-format logic
from `org-latex-src-block' into new dedicated functions:
+ `org-latex-src-block--verbatim'
+ `org-latex-src-block--custom'
+ `org-latex-src-block--minted'
+ `org-latex-src-block--listings'
This makes `org-latex-src-block' much less monolithic, taking it from
175 lines to 30, and I find also makes it easier to understand.
---
 lisp/ox-latex.el | 339 ++++++++++++++++++++++++++---------------------
 1 file changed, 185 insertions(+), 154 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 841ad48bc..c2f728a1c 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2997,164 +2997,195 @@ (defun org-latex-src-block (src-block _contents info)
 	   (float (plist-get attributes :float))
 	   (listings (plist-get info :latex-listings)))
       (cond
-       ;; Case 1.  No source fontification.
        ((or (not lang) (not listings))
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
-                                (org-export-format-code-default src-block info))))
-          (cond ((string= "multicolumn" float)
-                 (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
-                         (plist-get info :latex-default-figure-position)
-                         (if caption-above-p caption-str "")
-                         verbatim
-                         (if caption-above-p "" caption-str)))
-                (caption (concat
-                          (if caption-above-p caption-str "")
-                          verbatim
-                          (if caption-above-p "" (concat "\n" caption-str))))
-                (t verbatim))))
-       ;; Case 2.  Custom environment.
+        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (custom-env
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (formatted-src (org-export-format-code-default src-block info)))
-          (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
-	      (format "\\begin{%s}\n%s\\end{%s}\n"
-		      custom-env
-		      (concat (and caption-above-p caption-str)
-			      formatted-src
-			      (and (not caption-above-p) caption-str))
-		      custom-env)
-	    (format-spec custom-env
-			 `((?s . ,formatted-src)
-			   (?c . ,caption)
-			   (?f . ,float)
-			   (?l . ,(org-latex--label src-block info))
-			   (?o . ,(or (plist-get attributes :options) "")))))))
-       ;; Case 3.  Use minted package.
+        (org-latex-src-block--custom src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
-	(let* ((caption-str (org-latex--caption/label-string src-block info))
-	       (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
-			      (plist-get info :latex-default-figure-position)))
-	       (float-env
-		(cond
-		 ((string= "multicolumn" float)
-		  (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 (caption
-		  (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 ((string= "t" float)
-		  (concat (format "\\begin{listing}[%s]\n"
-				  placement)
-			  "%s\n\\end{listing}"))
-		 (t "%s")))
-	       (options (plist-get info :latex-minted-options))
-	       (body
-		(format
-		 "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
-		 ;; Options.
-		 (concat
-		  (org-latex--make-option-string
-		   (if (or (not num-start) (assoc "linenos" options))
-		       options
-		     (append
-		      `(("linenos")
-			("firstnumber" ,(number-to-string (1+ num-start))))
-		      options)))
-		  (let ((local-options (plist-get attributes :options)))
-		    (and local-options (concat "," local-options))))
-		 ;; Language.
-		 (or (cadr (assq (intern lang)
-				 (plist-get info :latex-minted-langs)))
-		     (downcase lang))
-		 ;; Source code.
-		 (let* ((code-info (org-export-unravel-code src-block))
-			(max-width
-			 (apply 'max
-				(mapcar 'length
-					(org-split-string (car code-info)
-							  "\n")))))
-		   (org-export-format-code
-		    (car code-info)
-		    (lambda (loc _num ref)
-		      (concat
-		       loc
-		       (when ref
-			 ;; Ensure references are flushed to the right,
-			 ;; separated with 6 spaces from the widest line
-			 ;; of code.
-			 (concat (make-string (+ (- max-width (length loc)) 6)
-					      ?\s)
-				 (format "(%s)" ref)))))
-		    nil (and retain-labels (cdr code-info)))))))
-	  ;; Return value.
-	  (format float-env body)))
-       ;; Case 4.  Use listings package.
+        (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (t
-	(let ((lst-lang
-	       (or (cadr (assq (intern lang)
-			       (plist-get info :latex-listings-langs)))
-		   lang))
-	      (caption-str
-	       (when caption
-		 (let ((main (org-export-get-caption src-block))
-		       (secondary (org-export-get-caption src-block t)))
-		   (if (not secondary)
-		       (format "{%s}" (org-export-data main info))
-		     (format "{[%s]%s}"
-			     (org-export-data secondary info)
-			     (org-export-data main info))))))
-	      (lst-opt (plist-get info :latex-listings-options)))
-	  (concat
-	   ;; Options.
-	   (format
-	    "\\lstset{%s}\n"
-	    (concat
-	     (org-latex--make-option-string
-	      (append
-	       lst-opt
-	       (cond
-		((and (not float) (plist-member attributes :float)) nil)
-		((string= "multicolumn" float) '(("float" "*")))
-		((and float (not (assoc "float" lst-opt)))
-		 `(("float" ,(plist-get info :latex-default-figure-position)))))
-	       `(("language" ,lst-lang))
-	       (if label
-		   `(("label" ,(org-latex--label src-block info)))
-		 '(("label" " ")))
-	       (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
-	       `(("captionpos" ,(if caption-above-p "t" "b")))
-	       (cond ((assoc "numbers" lst-opt) nil)
-		     ((not num-start) '(("numbers" "none")))
-		     (t `(("firstnumber" ,(number-to-string (1+ num-start)))
-			  ("numbers" "left"))))))
-	     (let ((local-options (plist-get attributes :options)))
-	       (and local-options (concat "," local-options)))))
-	   ;; Source code.
-	   (format
-	    "\\begin{lstlisting}\n%s\\end{lstlisting}"
-	    (let* ((code-info (org-export-unravel-code src-block))
-		   (max-width
-		    (apply 'max
-			   (mapcar 'length
-				   (org-split-string (car code-info) "\n")))))
-	      (org-export-format-code
-	       (car code-info)
-	       (lambda (loc _num ref)
-		 (concat
-		  loc
-		  (when ref
-		    ;; Ensure references are flushed to the right,
-		    ;; separated with 6 spaces from the widest line of
-		    ;; code
-		    (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
-			    (format "(%s)" ref)))))
-	       nil (and retain-labels (cdr code-info))))))))))))
-
+        (org-latex-src-block--listings src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))))))
+
+(defun org-latex-src-block--verbatim
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels _attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
+                          (org-export-format-code-default src-block info))))
+    (cond ((string= "multicolumn" float)
+           (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
+                   (plist-get info :latex-default-figure-position)
+                   (if caption-above-p caption-str "")
+                   verbatim
+                   (if caption-above-p "" caption-str)))
+          (caption (concat
+                    (if caption-above-p caption-str "")
+                    verbatim
+                    (if caption-above-p "" (concat "\n" caption-str))))
+          (t verbatim))))
+
+(defun org-latex-src-block--custom
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels attributes float custom-env)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (formatted-src (org-export-format-code-default src-block info)))
+    (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
+        (format "\\begin{%s}\n%s\\end{%s}\n"
+                custom-env
+                (concat (and caption-above-p caption-str)
+                        formatted-src
+                        (and (not caption-above-p) caption-str))
+                custom-env)
+      (format-spec custom-env
+                   `((?s . ,formatted-src)
+                     (?c . ,caption)
+                     (?f . ,float)
+                     (?l . ,(org-latex--label src-block info))
+                     (?o . ,(or (plist-get attributes :options) "")))))))
+
+(defun org-latex-src-block--minted
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-minted-options))
+         (body
+          (format
+           "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (if (or (not num-start) (assoc "linenos" options))
+                 options
+               (append
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start))))
+                options)))
+            (let ((local-options (plist-get attributes :options)))
+              (and local-options (concat "," local-options))))
+           ;; Language.
+           (or (cadr (assq (intern lang)
+                           (plist-get info :latex-minted-langs)))
+               (downcase lang))
+           ;; Source code.
+           (let* ((code-info (org-export-unravel-code src-block))
+                  (max-width
+                   (apply 'max
+                          (mapcar 'length
+                                  (org-split-string (car code-info)
+                                                    "\n")))))
+             (org-export-format-code
+              (car code-info)
+              (lambda (loc _num ref)
+                (concat
+                 loc
+                 (when ref
+                   ;; Ensure references are flushed to the right,
+                   ;; separated with 6 spaces from the widest line
+                   ;; of code.
+                   (concat (make-string (+ (- max-width (length loc)) 6)
+                                        ?\s)
+                           (format "(%s)" ref)))))
+              nil (and retain-labels (cdr code-info)))))))
+    ;; Return value.
+    (format float-env body)))
+
+(defun org-latex-src-block--listings
+    (src-block info lang caption caption-above-p label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((lst-lang
+         (or (cadr (assq (intern lang)
+                         (plist-get info :latex-listings-langs)))
+             lang))
+        (caption-str
+         (when caption
+           (let ((main (org-export-get-caption src-block))
+                 (secondary (org-export-get-caption src-block t)))
+             (if (not secondary)
+                 (format "{%s}" (org-export-data main info))
+               (format "{[%s]%s}"
+                       (org-export-data secondary info)
+                       (org-export-data main info))))))
+        (lst-opt (plist-get info :latex-listings-options)))
+    (concat
+     ;; Options.
+     (format
+      "\\lstset{%s}\n"
+      (concat
+       (org-latex--make-option-string
+        (append
+         lst-opt
+         (cond
+          ((and (not float) (plist-member attributes :float)) nil)
+          ((string= "multicolumn" float) '(("float" "*")))
+          ((and float (not (assoc "float" lst-opt)))
+           `(("float" ,(plist-get info :latex-default-figure-position)))))
+         `(("language" ,lst-lang))
+         (if label
+             `(("label" ,(org-latex--label src-block info)))
+           '(("label" " ")))
+         (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
+         `(("captionpos" ,(if caption-above-p "t" "b")))
+         (cond ((assoc "numbers" lst-opt) nil)
+               ((not num-start) '(("numbers" "none")))
+               (t `(("firstnumber" ,(number-to-string (1+ num-start)))
+                    ("numbers" "left"))))))
+       (let ((local-options (plist-get attributes :options)))
+         (and local-options (concat "," local-options)))))
+     ;; Source code.
+     (format
+      "\\begin{lstlisting}\n%s\\end{lstlisting}"
+      (let* ((code-info (org-export-unravel-code src-block))
+             (max-width
+              (apply 'max
+                     (mapcar 'length
+                             (org-split-string (car code-info) "\n")))))
+        (org-export-format-code
+         (car code-info)
+         (lambda (loc _num ref)
+           (concat
+            loc
+            (when ref
+              ;; Ensure references are flushed to the right,
+              ;; separated with 6 spaces from the widest line of
+              ;; code
+              (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
+                      (format "(%s)" ref)))))
+         nil (and retain-labels (cdr code-info))))))))
 
 ;;;; Statistics Cookie
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-ox-latex-Refactor-org-latex-inline-src-block.patch --]
[-- Type: text/x-patch, Size: 4016 bytes --]

From aa8406ce64507b870322495e8f9b54317930ed24 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 18:53:10 +0800
Subject: [PATCH 2/7] ox-latex: Refactor `org-latex-inline-src-block'

* lisp/ox-latex.el (org-latex-inline-src-block,
org-latex-inline-src-block--minted,
org-latex-inline-src-block--listings): Extract the minted and listings
specific logic out of `org-latex-inline-src-block` into the new
functions `org-latex-inline-src-block--minted` and
`org-latex-inline-src-block--listings`.
---
 lisp/ox-latex.el | 62 +++++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index c2f728a1c..38f36a1f3 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2127,36 +2127,38 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
   "Transcode an INLINE-SRC-BLOCK element from Org to LaTeX.
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
-  (let* ((code (org-element-property :value inline-src-block))
-	 (separator (org-latex--find-verb-separator code)))
-    (cl-case (plist-get info :latex-listings)
-      ;; Do not use a special package: transcode it verbatim, as code.
-      ((nil) (org-latex--text-markup code 'code info))
-      ;; Use minted package.
-      (minted
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (mint-lang (or (cadr (assq (intern org-lang)
-					 (plist-get info :latex-minted-langs)))
-			     (downcase org-lang)))
-	      (options (org-latex--make-option-string
-			(plist-get info :latex-minted-options))))
-	 (format "\\mintinline%s{%s}{%s}"
-		 (if (string= options "") "" (format "[%s]" options))
-		 mint-lang
-		 code)))
-      ;; Use listings package.
-      (otherwise
-       ;; Maybe translate language's name.
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (lst-lang (or (cadr (assq (intern org-lang)
-					(plist-get info :latex-listings-langs)))
-			    org-lang))
-	      (options (org-latex--make-option-string
-			(append (plist-get info :latex-listings-options)
-				`(("language" ,lst-lang))))))
-	 (concat (format "\\lstinline[%s]" options)
-		 separator code separator))))))
-
+  (let ((code (org-element-property :value inline-src-block))
+        (lang (org-element-property :language inline-src-block)))
+    (pcase (plist-get info :latex-listings)
+      ('nil (org-latex--text-markup code 'code info))
+      ('minted (org-latex-inline-src-block--minted info code lang))
+      (_ (org-latex-inline-src-block--listings info code lang)))))
+
+(defun org-latex-inline-src-block--minted (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using minted.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let ((mint-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-minted-langs)))
+                       (downcase lang)))
+        (options (org-latex--make-option-string
+                  (plist-get info :latex-minted-options))))
+    (format "\\mintinline%s{%s}{%s}"
+            (if (string= options "") "" (format "[%s]" options))
+            mint-lang
+            code)))
+
+(defun org-latex-inline-src-block--listings (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let* ((lst-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-listings-langs)))
+                       lang))
+         (separator (org-latex--find-verb-separator code))
+         (options (org-latex--make-option-string
+                   (append (plist-get info :latex-listings-options)
+                           `(("language" ,lst-lang))))))
+    (concat (format "\\lstinline[%s]" options)
+            separator code separator)))
 
 ;;;; Inlinetask
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-ox-latex-More-versitile-option-construction.patch --]
[-- Type: text/x-patch, Size: 4116 bytes --]

From 62d6703f0dd622916dff8aab960db6df4cb58cf7 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 23:31:59 +0800
Subject: [PATCH 3/7] ox-latex: More versitile option construction

* lisp/ox-latex.el (org-latex--make-option-string): Support a custom
option seperator string.

(org-latex--make-option-string, org-latex-minted-options,
org-latex-listings-options): The first line of the docstrings for
`org-latex-minted-options` and `org-latex-listings-options` describe the
variables as "association lists", yet `org-latex--make-option-string`
does not handle association lists and an example of two-value lists is
provided.  To make the behaviour match the docstring,
`org-latex--make-option-string` is modified to work with either a list
two-value lists or an association list, and the examples in
`org-latex-minted-options` and `org-latex-listings-options` updated
accordingly.
---
 lisp/ox-latex.el | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 38f36a1f3..2d4b3bace 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1006,12 +1006,16 @@ (defcustom org-latex-listings-options nil
 
 These options are supplied as a comma-separated list to the
 \\lstset command.  Each element of the association list should be
-a list containing two strings: the name of the option, and the
-value.  For example,
+a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-listings-options
     \\='((\"basicstyle\" \"\\\\small\")
       (\"keywordstyle\" \"\\\\color{black}\\\\bfseries\\\\underbar\")))
+  ; or
+  (setq org-latex-listings-options
+    \\='((\"basicstyle\" . \"\\\\small\")
+      (\"keywordstyle\" . \"\\\\color{black}\\\\bfseries\\\\underbar\")))
 
 will typeset the code in a small size font with underlined, bold
 black keywords.
@@ -1059,11 +1063,14 @@ (defcustom org-latex-minted-options nil
 
 These options are supplied within square brackets in
 \\begin{minted} environments.  Each element of the alist should
-be a list containing two strings: the name of the option, and the
-value.  For example,
+be a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-minted-options
     \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-minted-options
+    \\='((\"bgcolor\" . \"bg\") (\"frame\" . \"lines\")))
 
 will result in source blocks being exported with
 
@@ -1506,21 +1513,24 @@ (defun org-latex--find-verb-separator (s)
 	     when (not (string-match (regexp-quote (char-to-string c)) s))
 	     return (char-to-string c))))
 
-(defun org-latex--make-option-string (options)
+(defun org-latex--make-option-string (options &optional seperator)
   "Return a comma separated string of keywords and values.
 OPTIONS is an alist where the key is the options keyword as
 a string, and the value a list containing the keyword value, or
 nil."
   (mapconcat (lambda (pair)
-	       (pcase-let ((`(,keyword ,value) pair))
-		 (concat keyword
-			 (and (> (length value) 0)
-			      (concat "="
-                                      (if (string-match-p (rx (any "[]")) value)
-                                          (format "{%s}" value)
-                                        value))))))
-	     options
-	     ","))
+               (let ((keyword (car pair))
+                     (value (pcase (cdr pair)
+                              ((pred stringp) (cdr pair))
+                              ((pred consp) (cadr pair)))))
+                 (concat keyword
+                         (when value
+                           (concat "="
+                                   (if (string-match-p (rx (any "[]")) value)
+                                       (format "{%s}" value)
+                                     value))))))
+             options
+             (or seperator ",")))
 
 (defun org-latex--wrap-label (element output info)
   "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-ox-latex-Introduce-engraved-code-highlighting.patch --]
[-- Type: text/x-patch, Size: 17266 bytes --]

From 410fda41ae1efa67313ebbe2ada381c5d0f0a092 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 20:04:12 +0800
Subject: [PATCH 4/7] ox-latex: Introduce "engraved" code highlighting

* lisp/ox-latex.el (org-latex-src-block, org-latex-src-block--engraved,
org-latex-inline-src-block, org-latex-inline-src-block--engraved,
org-latex-template, org-latex-listings): Make use of the engraved-faces
package (available on ELPA) to provide an alternative LaTeX code
highlighting backend which functions similarly to htmlize.el for HTML
exports.

(org-latex-engraved-preamble, org-latex-engraved-options): Introduce
variables to construct the preamble for engraved code blocks.

* lisp/ox-beamer.el (org-beamer-template): Modify to add engrave-faces
preamble when applicable.
---
 lisp/ox-beamer.el |  11 ++
 lisp/ox-latex.el  | 276 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 278 insertions(+), 9 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 6be73c91e..4d40f6a1d 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -857,6 +857,17 @@ (defun org-beamer-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity
+                        info t))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity
+                  info t)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 2d4b3bace..b9c6d4c3e 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -37,6 +37,8 @@ (defvar org-latex-default-packages-alist)
 (defvar org-latex-packages-alist)
 (defvar orgtbl-exp-regexp)
 
+(declare-function engrave-faces-latex-gen-preamble "ext:engrave-faces-latex")
+(declare-function engrave-faces-latex-buffer "ext:engrave-faces-latex")
 
 \f
 ;;; Define Back-End
@@ -125,6 +127,8 @@ (org-export-define-backend 'latex
     (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
     (:latex-default-table-mode nil nil org-latex-default-table-mode)
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
+    (:latex-engraved-options nil nil org-latex-engraved-options)
+    (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -937,22 +941,48 @@ (defcustom org-latex-listings nil
   "Non-nil means export source code using the listings package.
 
 This package will fontify source code, possibly even with color.
-If you want to use this, you also need to make LaTeX use the
-listings package, and if you want to have color, the color
-package.  Just add these to `org-latex-packages-alist', for
-example using customize, or with something like:
+There are four implementations of this functionality you may
+choose from (ordered from least to most capable):
+1. Verbatim (nil)
+2. Listings (t)
+3. Minted (minted)
+4. Engraved (engraved)
+
+The first two options provide basic syntax
+highlighting (listings), or none at all (verbatim).
+
+When using listings, you also need to make use of the LaTeX
+\"listings\" package. The \"color\" package is also needed if you
+would like color too.  These can simply be added to
+`org-latex-packages-alist', using customise or something like:
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\"))
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\"))
 
-Alternatively,
+There are two further options for more comprehensive
+fontification. The first can be set with,
+
+  (setq org-latex-listings \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the engrave-faces
+package (availible from ELPA), and the fvextra LaTeX package be
+installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the tcolorbox LaTeX package in
+addition to fvextra.
+
+The second more comprehensive option can be set with,
 
   (setq org-latex-listings \\='minted)
 
-causes source code to be exported using the minted package as
-opposed to listings.  If you want to use minted, you need to add
-the minted package to `org-latex-packages-alist', for example
+which causes source code to be exported using the minted package
+as opposed to listings.  If you want to use minted, you need to
+add the minted package to `org-latex-packages-alist', for example
 using customize, or with
 
   (require \\='ox-latex)
@@ -971,8 +1001,9 @@ (defcustom org-latex-listings nil
   :type '(choice
 	  (const :tag "Use listings" t)
 	  (const :tag "Use minted" minted)
+	  (const :tag "Use engrave-faces-latex" engraved)
 	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted))))
+  :safe (lambda (s) (memq s '(t nil minted engraved))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1142,6 +1173,127 @@ (defcustom org-latex-custom-lang-environments nil
   :version "26.1"
   :package-version '(Org . "9.0"))
 
+(defcustom org-latex-engraved-preamble
+  "\\usepackage{fvextra}
+
+[FVEXTRA-SETUP]
+
+% Make line numbers smaller and grey.
+\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
+
+\\usepackage{xcolor}
+
+\\providecolor{codebackground}{HTML}{f7f7f7}
+\\providecolor{codeborder}{HTML}{f0f0f0}
+\\providecolor{EFD}{HTML}{28292e}
+
+% Define a Code environment to prettily wrap the fontified code.
+\\usepackage[breakable,xparse]{tcolorbox}
+\\DeclareTColorBox[]{Code}{o}%
+{colback=codebackground, colframe=codeborder,
+  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
+  colupper=EFD,
+  IfNoValueTF={#1}%
+  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
+    boxrule=0.5pt, left=2pt}%
+  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
+    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
+  right=2pt, top=1pt, bottom=0.5pt,
+  breakable}"
+  "Preamble content injected when using engrave-faces-latex for source blocks.
+This is relevant when `org-latex-listings' is set to `engraved'.
+
+There is quite a lot of flexibility in what this preamble can be, as long as it:
+- Loads the fvextra package.
+- Loads the package xcolor (if it is not already loader elsewhere).
+- Defines a \"Code\" environment (note the capital C), which all
+  \"Verbatim\" environments (provided by fvextra) will be wrapped with.
+
+A macro-like placeholder is used to set fvextra's defaults according to
+`org-latex-engraved-options':
+
+  [FVEXTRA-SETUP]
+
+In the default value the color \"EFD\" is provided as this is the
+foreground colour provided by engrave-faces-latex.  When there
+are example/fixed-width blocks only, the engraved generated
+preamble is not included, and so it is provided so we may use it
+anyway."
+  :group 'org-export-latex
+  :type 'string
+  :package-version '(Org . "9.6"))
+
+(defcustom org-latex-engraved-options
+  '(("commandchars" . "\\\\\\{\\}")
+    ("highlightcolor" . "white!95!black!80!blue")
+    ("breaklines" . "true")
+    ("breaksymbol" . "\\color{white!60!black}\\tiny\\ensuremath{\\hookrightarrow}"))
+  "Association list of options for the latex fvextra package when engraving code.
+
+These options are set using \\fvset{...} in the preamble of the
+LaTeX export.  Each element of the alist should be a list or cons
+cell containing two strings: the name of the option, and the
+value.  For example,
+
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" \"green\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" . \"green\") (\"frame\" . \"lines\")))
+
+will result in the following LaTeX in the preamble
+
+\\fvset{%
+  bgcolor=bg,
+  frame=lines}
+
+This will affect all fvextra environments.  Note that the same
+options will be applied to all blocks.  If you need
+block-specific options, you may use the following syntax:
+
+  #+ATTR_LATEX: :options key1=value1,key2=value2
+  #+BEGIN_SRC <LANG>
+  ...
+  #+END_SRC"
+  :group 'org-export-latex
+  :type '(alist :key-type (string :tag "option")
+                :value-type (string :tag "value")))
+
+(defun org-latex-generate-engraved-preamble (info syntax-colours-p)
+  "Generate the preamble to setup engraved code.
+The result is constructed from the :latex-engraved-preamble and
+:latex-engraved-optionsn export options, the default values of
+which are given by `org-latex-engraved-preamble' and
+`org-latex-engraved-options' respectively."
+  (let* ((engraved-options
+          (plist-get info :latex-engraved-options))
+         (engraved-preamble-template
+          (plist-get info :latex-engraved-preamble))
+         (engraved-preamble
+          (if (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?"
+                            engraved-preamble-template)
+              (replace-match
+               (concat
+                "\\fvset{%\n  "
+                (org-latex--make-option-string engraved-options ",\n  ")
+                "}\n")
+               t t
+               engraved-preamble-template)
+            engraved-preamble-template)))
+    (if syntax-colours-p
+        (concat
+         "\n% Setup for code blocks [1/2]\n\n"
+         engraved-preamble
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         (if (require 'engrave-faces-latex nil t)
+             (engrave-faces-latex-gen-preamble)
+           (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
+           "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
+         "\n")
+      (concat
+       "\n% Setup for code blocks\n\n"
+       engraved-preamble
+       "\n"))))
 
 ;;;; Compilation
 
@@ -1756,6 +1908,17 @@ (defun org-latex-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
             (format-spec template spec)))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity
+                        info t))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity
+                  info t)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
@@ -2142,6 +2305,7 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
     (pcase (plist-get info :latex-listings)
       ('nil (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
+      ('engraved (org-latex-inline-src-block--engraved info code lang))
       (_ (org-latex-inline-src-block--listings info code lang)))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
@@ -2157,6 +2321,24 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
+(defun org-latex-inline-src-block--engraved (_info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (if (require 'engrave-faces-latex nil t)
+      (let (engraved-buffer engraved-code)
+        (setq engraved-buffer
+              (with-temp-buffer
+                (insert code)
+                (funcall (org-src-get-lang-mode lang))
+                (engrave-faces-latex-buffer)))
+        (setq engraved-code
+              (with-current-buffer engraved-buffer
+                (buffer-string)))
+        (kill-buffer engraved-buffer)
+        (format "\\Verb{%s}"
+                engraved-code))
+    (user-error "Cannot engrave inline src block, `engrave-faces-latex' is unavailible.")))
+
 (defun org-latex-inline-src-block--listings (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
@@ -3017,6 +3199,9 @@ (defun org-latex-src-block (src-block _contents info)
                                      num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
         (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float))
+       ((eq listings 'engraved)
+        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
                                        num-start retain-labels attributes float))
        (t
         (org-latex-src-block--listings src-block info lang caption caption-above-p label
@@ -3133,6 +3318,79 @@ (defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
+(defun org-latex-src-block--engraved
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (if (require 'engrave-faces-latex nil t)
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-engraved-options))
+         (content-buffer
+          (with-temp-buffer
+            (insert
+             (let* ((code-info (org-export-unravel-code src-block))
+                    (max-width
+                     (apply 'max
+                            (mapcar 'length
+                                    (org-split-string (car code-info)
+                                                      "\n")))))
+               (org-export-format-code
+                (car code-info)
+                (lambda (loc _num ref)
+                  (concat
+                   loc
+                   (when ref
+                     ;; Ensure references are flushed to the right,
+                     ;; separated with 6 spaces from the widest line
+                     ;; of code.
+                     (concat (make-string (+ (- max-width (length loc)) 6)
+                                          ?\s)
+                             (format "(%s)" ref)))))
+                nil (and retain-labels (cdr code-info)))))
+            (funcall (org-src-get-lang-mode lang))
+            (engrave-faces-latex-buffer)))
+         (content
+          (with-current-buffer content-buffer
+            (buffer-string)))
+         (body
+          (format
+           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (append
+              (when (and num-start (not (assoc "linenos" options)))
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start)))))
+              (let ((local-options (plist-get attributes :options)))
+                (and local-options (list local-options))))))
+           content)))
+    (kill-buffer content-buffer)
+    ;; Return value.
+    (format float-env body))
+  (user-error "Cannot engrave src block, `engrave-faces-latex' is unavailible.")))
+
 (defun org-latex-src-block--listings
     (src-block info lang caption caption-above-p label
                num-start retain-labels attributes float)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-ox-latex-Don-t-use-length-to-get-string-width.patch --]
[-- Type: text/x-patch, Size: 2005 bytes --]

From 531a8bdd52bc6c9b7ba0da847809c76f14221bb1 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 13:59:13 +0800
Subject: [PATCH 5/7] ox-latex: Don't use `length' to get string width

* lisp/ox-latex.el (org-latex-src-block--listings,
org-latex-src-block--engraved, org-latex-src-block--minted): Use
`string-width' instead of `length' to gauge the displayed width of the
string in LaTeX.  This may not be a perfect match, but it should be an
improvement.
---
 lisp/ox-latex.el | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index b9c6d4c3e..6a794c41c 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3299,7 +3299,7 @@ (defun org-latex-src-block--minted
            (let* ((code-info (org-export-unravel-code src-block))
                   (max-width
                    (apply 'max
-                          (mapcar 'length
+                          (mapcar 'string-width
                                   (org-split-string (car code-info)
                                                     "\n")))))
              (org-export-format-code
@@ -3352,7 +3352,7 @@ (defun org-latex-src-block--engraved
              (let* ((code-info (org-export-unravel-code src-block))
                     (max-width
                      (apply 'max
-                            (mapcar 'length
+                            (mapcar 'string-width
                                     (org-split-string (car code-info)
                                                       "\n")))))
                (org-export-format-code
@@ -3442,7 +3442,7 @@ (defun org-latex-src-block--listings
       (let* ((code-info (org-export-unravel-code src-block))
              (max-width
               (apply 'max
-                     (mapcar 'length
+                     (mapcar 'string-width
                              (org-split-string (car code-info) "\n")))))
         (org-export-format-code
          (car code-info)
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: 0006-ox-latex-Refactor-source-block-transcode-fun-sigs.patch --]
[-- Type: text/x-patch, Size: 7091 bytes --]

From 1961039336917e6f4e3698aadccc03444dfc2592 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 14:02:44 +0800
Subject: [PATCH 6/7] ox-latex: Refactor source block transcode fun sigs

* lisp/ox-latex.el (org-latex-src-block--listings,
org-latex-src-block--engraved, org-latex-src-block--minted,
org-latex-src-block--custom): Refactor these --backend functions to use
cl-defun with keys instead of having an 11-argument signature.
(org-latex-src-block): Adjust for the change in signature of the
--backend functions, and refactor the `cond' statement to use `pcase'.
---
 lisp/ox-latex.el | 78 +++++++++++++++++++++++-------------------------
 1 file changed, 37 insertions(+), 41 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 6a794c41c..685899c7d 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -3179,37 +3179,37 @@ (defun org-latex-src-block (src-block _contents info)
 contextual information."
   (when (org-string-nw-p (org-element-property :value src-block))
     (let* ((lang (org-element-property :language src-block))
-	   (caption (org-element-property :caption src-block))
-	   (caption-above-p (org-latex--caption-above-p src-block info))
-	   (label (org-element-property :name src-block))
-	   (custom-env (and lang
-			    (cadr (assq (intern lang)
-					org-latex-custom-lang-environments))))
-	   (num-start (org-export-get-loc src-block info))
-	   (retain-labels (org-element-property :retain-labels src-block))
-	   (attributes (org-export-read-attribute :attr_latex src-block))
-	   (float (plist-get attributes :float))
-	   (listings (plist-get info :latex-listings)))
-      (cond
-       ((or (not lang) (not listings))
-        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))
-       (custom-env
-        (org-latex-src-block--custom src-block info lang caption caption-above-p label
-                                     num-start retain-labels attributes float custom-env))
-       ((eq listings 'minted)
-        (org-latex-src-block--minted src-block info lang caption caption-above-p label
-                                     num-start retain-labels attributes float))
-       ((eq listings 'engraved)
-        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))
-       (t
-        (org-latex-src-block--listings src-block info lang caption caption-above-p label
-                                       num-start retain-labels attributes float))))))
-
-(defun org-latex-src-block--verbatim
-    (src-block info _lang caption caption-above-p _label
-               _num-start _retain-labels _attributes float)
+           (caption (org-element-property :caption src-block))
+           (caption-above-p (org-latex--caption-above-p src-block info))
+           (label (org-element-property :name src-block))
+           (custom-env (and lang
+                            (cadr (assq (intern lang)
+                                        org-latex-custom-lang-environments))))
+           (num-start (org-export-get-loc src-block info))
+           (retain-labels (org-element-property :retain-labels src-block))
+           (attributes (org-export-read-attribute :attr_latex src-block))
+           (float (plist-get attributes :float))
+           (listings (plist-get info :latex-listings)))
+      (funcall
+       (pcase listings
+         ((or (pred not) (guard (not lang))) #'org-latex-src-block--verbatim
+          ((guard custom-env) #'org-latex-src-block--custom)
+          ('minted #'org-latex-src-block--minted)
+          ('engraved #'org-latex-src-block--engraved)
+          (_ #'org-latex-src-block--listings)))
+       :src-block src-block
+       :info info
+       :lang lang
+       :caption caption
+       :caption-above-p caption-above-p
+       :label label
+       :num-start num-start
+       :retain-labels retain-labels
+       :attributes attributes
+       :float float))))
+
+(cl-defun org-latex-src-block--verbatim
+    (&key src-block info caption caption-above-p float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3228,9 +3228,8 @@ (defun org-latex-src-block--verbatim
                     (if caption-above-p "" (concat "\n" caption-str))))
           (t verbatim))))
 
-(defun org-latex-src-block--custom
-    (src-block info _lang caption caption-above-p _label
-               _num-start _retain-labels attributes float custom-env)
+(cl-defun org-latex-src-block--custom
+    (&key src-block info caption caption-above-p attributes float custom-env &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3251,8 +3250,7 @@ (defun org-latex-src-block--custom
                      (?o . ,(or (plist-get attributes :options) "")))))))
 
 (defun org-latex-src-block--minted
-    (src-block info lang caption caption-above-p _label
-               num-start retain-labels attributes float)
+    (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3319,8 +3317,7 @@ (defun org-latex-src-block--minted
     (format float-env body)))
 
 (defun org-latex-src-block--engraved
-    (src-block info lang caption caption-above-p _label
-               num-start retain-labels attributes float)
+    (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
@@ -3391,9 +3388,8 @@ (defun org-latex-src-block--engraved
     (format float-env body))
   (user-error "Cannot engrave src block, `engrave-faces-latex' is unavailible.")))
 
-(defun org-latex-src-block--listings
-    (src-block info lang caption caption-above-p label
-               num-start retain-labels attributes float)
+(cl-defun org-latex-src-block--listings
+    (&key src-block info lang caption caption-above-p label num-start retain-labels attributes float &allow-other-keys)
   "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
 LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
 and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #8: 0007-ox-latex-Replace-org-latex-listings.patch --]
[-- Type: text/x-patch, Size: 16140 bytes --]

From 4d24b74e5490a30c75c7a23721c836a8ce4756b6 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sat, 7 May 2022 14:46:28 +0800
Subject: [PATCH 7/7] ox-latex: Replace `org-latex-listings'

* lisp/ox-latex.el (org-latex-src-block, org-latex-keyword,
org-latex-inline-src-block, org-latex-template,
org-latex--caption/label-string, org-latex-engraved-preamble,
org-latex-listings): Replace `org-latex-listings' with
`org-latex-src-block-backend', which now can be set to listings/verbatim
and no longer advertises t/nil as valid values.

* lisp/ox-beamer.el (org-beamer-template): Update in the same manner as
`org-latex-template'.

* lisp/org-compat.el: Make `org-latex-listings' an obsolete alias for
`org-latex-src-block-backend'.

* testing/lisp/test-ox.el: Replace `org-latex-listings' reference with
`org-latex-src-block-backend'.

* doc/org-manual.org (Footnotes, LaTeX specific properties, Literal
Examples): Replace references to `org-latex-listings' with
`org-latex-src-block-backend'.

* etc/ORG-NEWS: Add a news entry noting this change.

The variable `org-latex-listings' originally indicated whether source
blocks should use the listings LaTeX package, or not.  This usage has
evolved over the years, and now it sets one of four different
fontification backends.  This renaming should make the variable name a
bit less misleading.
---
 doc/org-manual.org      |   6 +--
 etc/ORG-NEWS            |   9 ++++
 lisp/org-compat.el      |   2 +
 lisp/ox-beamer.el       |   2 +-
 lisp/ox-latex.el        | 111 ++++++++++++++++++++++------------------
 testing/lisp/test-ox.el |   2 +-
 6 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index c0d38cd8c..60bded419 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -11159,7 +11159,7 @@ ** Literal Examples
 #+end_example
 
 #+cindex: formatting source code, markup rules
-#+vindex: org-latex-listings
+#+vindex: org-latex-src-block-backend
 If the example is source code from a programming language, or any
 other text that can be marked up by Font Lock in Emacs, you can ask
 for the example to look like the fontified Emacs buffer[fn:114].  This
@@ -16304,12 +16304,12 @@ **** LaTeX specific properties
 | ~:latex-link-with-unknown-path-format~ | ~org-latex-link-with-unknown-path-format~ |
 | ~:latex-listings-langs~                | ~org-latex-listings-langs~                |
 | ~:latex-listings-options~              | ~org-latex-listings-options~              |
-| ~:latex-listings~                      | ~org-latex-listings~                      |
 | ~:latex-minted-langs~                  | ~org-latex-minted-langs~                  |
 | ~:latex-minted-options~                | ~org-latex-minted-options~                |
 | ~:latex-prefer-user-labels~            | ~org-latex-prefer-user-labels~            |
 | ~:latex-subtitle-format~               | ~org-latex-subtitle-format~               |
 | ~:latex-subtitle-separate~             | ~org-latex-subtitle-separate~             |
+| ~:latex-src-block-backend~             | ~org-latex-src-block-backend~             |
 | ~:latex-table-scientific-notation~     | ~org-latex-table-scientific-notation~     |
 | ~:latex-tables-booktabs~               | ~org-latex-tables-booktabs~               |
 | ~:latex-tables-centered~               | ~org-latex-tables-centered~               |
@@ -22256,7 +22256,7 @@ * Footnotes
 version 1.34 of the =htmlize.el= package, which you need to install).
 Fontified code chunks in LaTeX can be achieved using either the
 [[https://www.ctan.org/pkg/listings][listings]] package or the [[https://www.ctan.org/pkg/minted][minted]] package.  Refer to
-~org-latex-listings~ for details.
+~org-latex-src-block-backend~ for details.
 
 [fn:115] Source code in code blocks may also be evaluated either
 interactively or on export.  See [[*Working with Source Code]] for more
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 1e8558c7b..c5f0bcb33 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -268,6 +268,15 @@ Chmod-style permissions are based on the new variable
 ~org-babel-tangle-default-file-mode~.
 
 *** A new custom setting =org-agenda-clock-report-header= to add a header to org agenda clock report
+
+*** ~org-latex-listings~ has been replaced with ~org-latex-src-block-backend~
+
+~org-latex-listings~ has been renamed to better reflect the current
+purpose of the variable.  The replacement variable
+~org-latex-src-block-backend~ acts in exactly the same way, however it
+accepts =listings= and =verbatim= in place of =t= and =nil= (which
+still work, but are no longer listed as valid options).
+
 * Version 9.5
 
 ** Important announcements and breaking changes
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index f599e246e..c1a78e834 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -324,6 +324,8 @@ (define-obsolete-variable-alias 'org-latex-create-formula-image-program
   'org-preview-latex-default-process "9.0")
 (define-obsolete-variable-alias 'org-latex-preview-ltxpng-directory
   'org-preview-latex-image-directory "9.0")
+(define-obsolete-variable-alias 'org-latex-listings
+  'org-latex-src-block-backend "9.6")
 (define-obsolete-function-alias 'org-table-p 'org-at-table-p "9.0")
 (define-obsolete-function-alias 'org-on-heading-p 'org-at-heading-p "9.0")
 (define-obsolete-function-alias 'org-at-regexp-p 'org-in-regexp "8.3")
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 4d40f6a1d..3baa4e26e 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -858,7 +858,7 @@ (defun org-beamer-template (contents info)
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
      ;; engrave-faces-latex preamble
-     (when (eq org-latex-listings 'engraved)
+     (when (eq org-latex-src-block-backend 'engraved)
        (let ((src-p (org-element-map (plist-get info :parse-tree)
                         '(src-block inline-src-block) #'identity
                         info t))
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 685899c7d..8f4206164 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -143,7 +143,7 @@ (org-export-define-backend 'latex
     (:latex-inactive-timestamp-format nil nil org-latex-inactive-timestamp-format)
     (:latex-inline-image-rules nil nil org-latex-inline-image-rules)
     (:latex-link-with-unknown-path-format nil nil org-latex-link-with-unknown-path-format)
-    (:latex-listings nil nil org-latex-listings)
+    (:latex-src-block-backend nil nil org-latex-src-block-backend)
     (:latex-listings-langs nil nil org-latex-listings-langs)
     (:latex-listings-options nil nil org-latex-listings-options)
     (:latex-minted-langs nil nil org-latex-minted-langs)
@@ -937,22 +937,22 @@ (defcustom org-latex-format-inlinetask-function
 
 ;; Src blocks
 
-(defcustom org-latex-listings nil
-  "Non-nil means export source code using the listings package.
+(defcustom org-latex-src-block-backend 'verbatim
+  "Backend used to generate source code listings.
 
-This package will fontify source code, possibly even with color.
-There are four implementations of this functionality you may
+This sets the behaviour for fontifying source code, possibly even with
+color.  There are four implementations of this functionality you may
 choose from (ordered from least to most capable):
-1. Verbatim (nil)
-2. Listings (t)
-3. Minted (minted)
-4. Engraved (engraved)
+1. Verbatim
+2. Listings
+3. Minted
+4. Engraved
 
 The first two options provide basic syntax
 highlighting (listings), or none at all (verbatim).
 
-When using listings, you also need to make use of the LaTeX
-\"listings\" package. The \"color\" package is also needed if you
+When using listings, you also need to make use of LaTeX package
+\"listings\"e. The \"color\" LaTeX package is also needed if you
 would like color too.  These can simply be added to
 `org-latex-packages-alist', using customise or something like:
 
@@ -963,27 +963,12 @@ (defcustom org-latex-listings nil
 There are two further options for more comprehensive
 fontification. The first can be set with,
 
-  (setq org-latex-listings \\='engraved)
+  (setq org-latex-src-block-backend \\='minted)
 
-which causes source code to be run through
-`engrave-faces-latex-buffer', which generates colorings using
-Emacs' font-lock information.  This requires the engrave-faces
-package (availible from ELPA), and the fvextra LaTeX package be
-installed.
-
-The styling of the engraved result can customised with
-`org-latex-engraved-preamble' and `org-latex-engraved-options'.
-The default preamble also uses the tcolorbox LaTeX package in
-addition to fvextra.
-
-The second more comprehensive option can be set with,
-
-  (setq org-latex-listings \\='minted)
-
-which causes source code to be exported using the minted package
-as opposed to listings.  If you want to use minted, you need to
-add the minted package to `org-latex-packages-alist', for example
-using customize, or with
+which causes source code to be exported using the LaTeX package
+minted as opposed to listings.  If you want to use minted, you
+need to add the minted package to `org-latex-packages-alist', for
+example using customize, or with
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"newfloat\" \"minted\"))
@@ -996,14 +981,29 @@ (defcustom org-latex-listings nil
 The minted choice has possible repercussions on the preview of
 latex fragments (see `org-preview-latex-fragment').  If you run
 into previewing problems, please consult
-URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'."
+URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'.
+
+The most comprehensive option can be set with,
+
+  (setq org-latex-src-block-backend \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the Emacs package
+engrave-faces (availible from ELPA), and the LaTeX package
+fvextra be installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the LaTeX package tcolorbox in
+addition to fvextra."
   :group 'org-export-latex
   :type '(choice
-	  (const :tag "Use listings" t)
+	  (const :tag "Use listings" listings)
 	  (const :tag "Use minted" minted)
 	  (const :tag "Use engrave-faces-latex" engraved)
-	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted engraved))))
+	  (const :tag "Export verbatim" verbatim))
+  :safe (lambda (s) (memq s '(listings minted engraved verbatim))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1201,7 +1201,7 @@ (defcustom org-latex-engraved-preamble
   right=2pt, top=1pt, bottom=0.5pt,
   breakable}"
   "Preamble content injected when using engrave-faces-latex for source blocks.
-This is relevant when `org-latex-listings' is set to `engraved'.
+This is relevant when `org-latex-src-block-backend' is set to `engraved'.
 
 There is quite a lot of flexibility in what this preamble can be, as long as it:
 - Loads the fvextra package.
@@ -1502,7 +1502,8 @@ (defun org-latex--caption/label-string (element info)
 			    main)
 		       (and (eq type 'src-block)
 			    (not (plist-get attr :float))
-			    (null (plist-get info :latex-listings)))))
+			    (memq (plist-get info :latex-src-block-backend)
+                                  '(verbatim nil)))))
 	 (short (org-export-get-caption element t))
 	 (caption-from-attr-latex (plist-get attr :caption)))
     (cond
@@ -1522,7 +1523,8 @@ (defun org-latex--caption/label-string (element info)
 		      (paragraph "figure")
 		      (image "figure")
 		      (special-block "figure")
-		      (src-block (if (plist-get info :latex-listings)
+		      (src-block (if (not (memq (plist-get info :latex-src-block-backend)
+                                                '(verbatim nil)))
 				     "listing"
 				   "figure"))
 		      (t (symbol-name type*)))
@@ -1909,7 +1911,7 @@ (defun org-latex-template (contents info)
        (and (stringp template)
             (format-spec template spec)))
      ;; engrave-faces-latex preamble
-     (when (eq org-latex-listings 'engraved)
+     (when (eq org-latex-src-block-backend 'engraved)
        (let ((src-p (org-element-map (plist-get info :parse-tree)
                         '(src-block inline-src-block) #'identity
                         info t))
@@ -2302,11 +2304,17 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
 contextual information."
   (let ((code (org-element-property :value inline-src-block))
         (lang (org-element-property :language inline-src-block)))
-    (pcase (plist-get info :latex-listings)
-      ('nil (org-latex--text-markup code 'code info))
+    (pcase (plist-get info :latex-src-block-backend)
+      ('verbatim (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
       ('engraved (org-latex-inline-src-block--engraved info code lang))
-      (_ (org-latex-inline-src-block--listings info code lang)))))
+      ('listings (org-latex-inline-src-block--listings info code lang))
+      (oldval
+       (message "Please update the LaTeX src-block-backend to %s"
+                (if oldval "listings" "verbatim"))
+       (if oldval
+           (org-latex-inline-src-block--listings info code lang)
+         (org-latex--text-markup code 'code info))))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using minted.
@@ -2502,7 +2510,7 @@ (defun org-latex-keyword (keyword _contents info)
 	      (concat depth (and depth "\n") "\\tableofcontents"))))
 	 ((string-match-p "\\<tables\\>" value) "\\listoftables")
 	 ((string-match-p "\\<listings\\>" value)
-	  (cl-case (plist-get info :latex-listings)
+	  (cl-case (plist-get info :latex-src-block-backend)
 	    ((nil) "\\listoffigures")
 	    (minted "\\listoflistings")
 	    (otherwise "\\lstlistoflistings")))))))))
@@ -3188,15 +3196,20 @@ (defun org-latex-src-block (src-block _contents info)
            (num-start (org-export-get-loc src-block info))
            (retain-labels (org-element-property :retain-labels src-block))
            (attributes (org-export-read-attribute :attr_latex src-block))
-           (float (plist-get attributes :float))
-           (listings (plist-get info :latex-listings)))
+           (float (plist-get attributes :float)))
       (funcall
-       (pcase listings
-         ((or (pred not) (guard (not lang))) #'org-latex-src-block--verbatim
-          ((guard custom-env) #'org-latex-src-block--custom)
+       (pcase (plist-get info :latex-src-block-backend)
+         ((or 'verbatim (guard (not lang))) #'org-latex-src-block--verbatim
           ('minted #'org-latex-src-block--minted)
           ('engraved #'org-latex-src-block--engraved)
-          (_ #'org-latex-src-block--listings)))
+          ('listings #'org-latex-src-block--listings)
+          ((guard custom-env) #'org-latex-src-block--custom)
+          (oldval
+           (message "Please update the LaTeX src-block-backend to %s"
+                    (if oldval "listings" "verbatim"))
+           (if oldval
+               #'org-latex-src-block--listings
+             #'org-latex-src-block--verbatim))))
        :src-block src-block
        :info info
        :lang lang
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 25e02b258..28f950813 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -3978,7 +3978,7 @@ (ert-deftest test-org-export/latex-src-block-verbatim-caption ()
 \\end{verbatim}
 \\caption{Caption is below, 60\\%s}
 \\end{figure*}"
-	     (let ((org-latex-listings 'minted) ; inactive due to missing lang
+	     (let ((org-latex-src-block-backend 'minted) ; inactive due to missing lang
 		   (org-latex-default-figure-position "tp"))
 	       ;; Namely "multicolumn" value to get just figure environment
 	       ;; looks like a bug.
-- 
2.35.3


^ permalink raw reply related	[relevance 3%]

* Re: [PATCH] New LaTeX code export option: engraved
  2022-05-05 15:17  4%   ` Timothy
@ 2022-05-05 16:13  8%     ` Timothy
    0 siblings, 1 reply; 200+ results
From: Timothy @ 2022-05-05 16:13 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode, Daniel Fleischer, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 166 bytes --]

> [5. text/x-patch; 0004-ox-latex-Introduce-engraved-code-highlighting.patch]…

Ooops, I had some ucommited changes. The correct version is attached.

Timothy

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Introduce-engraved-code-highlighting.patch --]
[-- Type: text/x-patch, Size: 17470 bytes --]

From b66c291b1f0d1419742449bcde42bf0c4d620c23 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 20:04:12 +0800
Subject: [PATCH] ox-latex: Introduce "engraved" code highlighting

* lisp/ox-latex.el (org-latex-src-block, org-latex-src-block--engraved,
org-latex-inline-src-block, org-latex-inline-src-block--engraved,
org-latex-template, org-latex-listings): Make use of the engraved-faces
package (available on ELPA) to provide an alternative LaTeX code
highlighting backend which functions similarly to htmlize.el for HTML
exports.

(org-latex-engraved-preamble, org-latex-engraved-options): Introduce
variables to construct the preamble for engraved code blocks.

* lisp/ox-beamer.el (org-beamer-template): Modify to add engrave-faces
preamble when applicable.
---
 lisp/ox-beamer.el |   9 ++
 lisp/ox-latex.el  | 273 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 272 insertions(+), 10 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 6be73c91e..73bd95539 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -857,6 +857,15 @@ (defun org-beamer-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 4181db175..83bb6f078 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -37,6 +37,8 @@ (defvar org-latex-default-packages-alist)
 (defvar org-latex-packages-alist)
 (defvar orgtbl-exp-regexp)
 
+(declare-function engrave-faces-latex-gen-preamble "ext:engrave-faces-latex")
+(declare-function engrave-faces-latex-buffer "ext:engrave-faces-latex")
 
 \f
 ;;; Define Back-End
@@ -125,6 +127,8 @@ (org-export-define-backend 'latex
     (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
     (:latex-default-table-mode nil nil org-latex-default-table-mode)
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
+    (:latex-engraved-options nil nil org-latex-engraved-options)
+    (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -937,22 +941,48 @@ (defcustom org-latex-listings nil
   "Non-nil means export source code using the listings package.
 
 This package will fontify source code, possibly even with color.
-If you want to use this, you also need to make LaTeX use the
-listings package, and if you want to have color, the color
-package.  Just add these to `org-latex-packages-alist', for
-example using customize, or with something like:
+There are four implementations of this functionality you may
+choose from (ordered from least to most capable):
+1. Verbatim (nil)
+2. Listings (t)
+3. Minted (minted)
+4. Engraved (engraved)
+
+The first two options provide basic syntax
+highlighting (listings), or none at all (verbatim).
+
+When using listings, you also need to make use of the LaTeX
+\"listings\" package. The \"color\" package is also needed if you
+would like color too.  These can simply be added to
+`org-latex-packages-alist', using customise or something like:
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\"))
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\"))
 
-Alternatively,
+There are two options for more comprehensive fontification. The
+first can be set with,
+
+  (setq org-latex-listings \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the engrave-faces
+package (availible from ELPA), and the fvextra LaTeX package be
+installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the tcolorbox LaTeX package in
+addition to fvextra.
+
+The second more comprehensive option can be used with,
 
   (setq org-latex-listings \\='minted)
 
-causes source code to be exported using the minted package as
-opposed to listings.  If you want to use minted, you need to add
-the minted package to `org-latex-packages-alist', for example
+which causes source code to be exported using the minted package
+as opposed to listings.  If you want to use minted, you need to
+add the minted package to `org-latex-packages-alist', for example
 using customize, or with
 
   (require \\='ox-latex)
@@ -971,8 +1001,9 @@ (defcustom org-latex-listings nil
   :type '(choice
 	  (const :tag "Use listings" t)
 	  (const :tag "Use minted" minted)
+	  (const :tag "Use engrave-faces-latex" engraved)
 	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted))))
+  :safe (lambda (s) (memq s '(t nil minted engraved))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1142,6 +1173,124 @@ (defcustom org-latex-custom-lang-environments nil
   :version "26.1"
   :package-version '(Org . "9.0"))
 
+(defcustom org-latex-engraved-preamble
+  "\\usepackage{fvextra}
+
+[FVEXTRA-SETUP]
+
+\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
+
+\\usepackage{xcolor}
+
+\\providecolor{codebackground}{HTML}{f7f7f7}
+\\providecolor{codeborder}{HTML}{f0f0f0}
+\\providecolor{EFD}{HTML}{28292e}
+
+% TODO have code boxes keep line vertical alignment
+\\usepackage[breakable,xparse]{tcolorbox}
+\\DeclareTColorBox[]{Code}{o}%
+{colback=codebackground, colframe=codeborder,
+  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
+  colupper=EFD,
+  IfNoValueTF={#1}%
+  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
+    boxrule=0.5pt, left=2pt}%
+  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
+    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
+  right=2pt, top=1pt, bottom=0.5pt,
+  breakable}"
+  "Preamble content injected when using engrave-faces-latex for source blocks.
+This is relevant when `org-latex-listings' is set to `engraved'.
+
+There is quite a lot of flexibility in what this preamble can be, as long as it:
+- Loads the fvextra package.
+- Loads the package xcolor (if it is not already loader elsewhere).
+- Defines a \"Code\" environment (note the capital C), which can be
+  later used to wrap \"Verbatim\" environments (provided by fvextra).
+
+A macro-like placeholder is used to set fvextra's defaults according to
+`org-latex-engraved-options':
+
+  [FVEXTRA-SETUP]
+
+In the default value the color \"EFD\" is provided as this is the
+foreground colour provided by engrave-faces-latex.  When there
+are example/fixed-width blocks only, the engraved generated
+preamble is not included, and so it is provided so we may use it
+anyway."
+  :group 'org-export-latex
+  :type 'string
+  :package-version '(Org . "9.6"))
+
+(defcustom org-latex-engraved-options
+  '(("commandchars" . "\\\\\\{\\}")
+    ("highlightcolor" . "white!95!black!80!blue")
+    ("breaklines" . "true")
+    ("breaksymbol" . "\\color{white!60!black}\\tiny\\ensuremath{\\hookrightarrow}"))
+  "Association list of options for the latex fvextra package when engraving code.
+
+These options are set using \\fvset{...} in the preamble of the
+LaTeX export.  Each element of the alist should be a list or cons
+cell containing two strings: the name of the option, and the
+value.  For example,
+
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" \"green\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" . \"green\") (\"frame\" . \"lines\")))
+
+will result in the following LaTeX in the preamble
+
+\\fvset{%
+  bgcolor=bg,
+  frame=lines}
+
+This will affect all fvextra environments.  Note that the same
+options will be applied to all blocks.  If you need
+block-specific options, you may use the following syntax:
+
+  #+ATTR_LATEX: :options key1=value1,key2=value2
+  #+BEGIN_SRC <LANG>
+  ...
+  #+END_SRC"
+  :group 'org-export-latex
+  :type '(alist :key-type (string :tag "option")
+                :value-type (string :tag "value")))
+
+(defun org-latex-generate-engraved-preamble (info syntax-colours-p)
+  "Generate the preamble to setup engraved code.
+The result is constructed from `org-latex-engraved-preamble' and
+`org-latex-engraved-options'."
+  (let* ((engraved-options
+          (plist-get info :latex-engraved-options))
+         (engraved-preamble-template
+          (plist-get info :latex-engraved-preamble))
+         (engraved-preamble
+          (if (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?"
+                            engraved-preamble-template)
+              (replace-match
+               (concat
+                "\\fvset{%\n  "
+                (org-latex--make-option-string engraved-options ",\n  ")
+                "}\n")
+               t t
+               engraved-preamble-template)
+            engraved-preamble-template)))
+    (if syntax-colours-p
+        (concat
+         "\n% Setup for code blocks [1/2]\n\n"
+         engraved-preamble
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         (if (require 'engrave-faces-latex nil t)
+             (engrave-faces-latex-gen-preamble)
+           (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
+           "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
+         "\n")
+      (concat
+       "\n% Setup for code blocks\n\n"
+       engraved-preamble
+       "\n"))))
 
 ;;;; Compilation
 
@@ -1756,6 +1905,15 @@ (defun org-latex-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
             (format-spec template spec)))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
@@ -2142,6 +2300,7 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
     (pcase (plist-get info :latex-listings)
       ('nil (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
+      ('engraved (org-latex-inline-src-block--engraved info code lang))
       (_ (org-latex-inline-src-block--listings info code lang)))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
@@ -2149,7 +2308,7 @@ (defun org-latex-inline-src-block--minted (info code lang)
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
   (let ((mint-lang (or (cadr (assq (intern lang)
                                    (plist-get info :latex-minted-langs)))
-                       (downcase org-lang)))
+                       (downcase lang)))
         (options (org-latex--make-option-string
                   (plist-get info :latex-minted-options))))
     (format "\\mintinline%s{%s}{%s}"
@@ -2157,6 +2316,24 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
+(defun org-latex-inline-src-block--engraved (_info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (if (require 'engrave-faces-latex nil t)
+      (let (engraved-buffer engraved-code)
+        (setq engraved-buffer
+              (with-temp-buffer
+                (insert code)
+                (funcall (org-src-get-lang-mode lang))
+                (engrave-faces-latex-buffer)))
+        (setq engraved-code
+              (with-current-buffer engraved-buffer
+                (buffer-string)))
+        (kill-buffer engraved-buffer)
+        (format "\\Verb{%s}"
+                engraved-code))
+    (user-error "Cannot engrave inline src block, `engrave-faces-latex' is unavailible.")))
+
 (defun org-latex-inline-src-block--listings (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
@@ -3017,6 +3194,9 @@ (defun org-latex-src-block (src-block _contents info)
                                      num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
         (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float))
+       ((eq listings 'engraved)
+        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
                                        num-start retain-labels attributes float))
        (t
         (org-latex-src-block--listings src-block info lang caption caption-above-p label
@@ -3133,6 +3313,79 @@ (defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
+(defun org-latex-src-block--engraved
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (if (require 'engrave-faces-latex nil t)
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-engraved-options))
+         (content-buffer
+          (with-temp-buffer
+            (insert
+             (let* ((code-info (org-export-unravel-code src-block))
+                    (max-width
+                     (apply 'max
+                            (mapcar 'length
+                                    (org-split-string (car code-info)
+                                                      "\n")))))
+               (org-export-format-code
+                (car code-info)
+                (lambda (loc _num ref)
+                  (concat
+                   loc
+                   (when ref
+                     ;; Ensure references are flushed to the right,
+                     ;; separated with 6 spaces from the widest line
+                     ;; of code.
+                     (concat (make-string (+ (- max-width (length loc)) 6)
+                                          ?\s)
+                             (format "(%s)" ref)))))
+                nil (and retain-labels (cdr code-info)))))
+            (funcall (org-src-get-lang-mode lang))
+            (engrave-faces-latex-buffer)))
+         (content
+          (with-current-buffer content-buffer
+            (buffer-string)))
+         (body
+          (format
+           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (append
+              (when (and num-start (not (assoc "linenos" options)))
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start)))))
+              (let ((local-options (plist-get attributes :options)))
+                (and local-options (list local-options))))))
+           content)))
+    (kill-buffer content-buffer)
+    ;; Return value.
+    (format float-env body))
+  (user-error "Cannot engrave src block, `engrave-faces-latex' is unavailible.")))
+
 (defun org-latex-src-block--listings
     (src-block info lang caption caption-above-p label
                num-start retain-labels attributes float)
-- 
2.35.3


^ permalink raw reply related	[relevance 8%]

* Re: [PATCH] New LaTeX code export option: engraved
  @ 2022-05-05 15:17  4%   ` Timothy
  2022-05-05 16:13  8%     ` Timothy
  0 siblings, 1 reply; 200+ results
From: Timothy @ 2022-05-05 15:17 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode, Daniel Fleischer, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 2879 bytes --]

Hi Ihor,

> Thanks!
> Implementing fontification using Emacs capabilities is certainly a step
> in the right direction. LaTeX support for fontification has always been
> tricky.

I’m glad to hear you’re of a similar mind to me with this.

> - I tried to test your patch, and it only works partially. There is some
>   stray text caused by LaTeX errors:
>
> [2. application/vnd.lotus-organizer; test.org]…
> [3. application/pdf; test.pdf]…

Ah. I thought that hyperref loaded xcolor, but it seems my assumption was
incorrect. I’ve added `\usepackage{xcolor}' to the default
`org-latex-engraved-preamble', but maybe I should ask people to modify
`org-latex-packages-alist'. I’m not sure.

> - You did not add a NEWS entry and did not update the manual in your patch.

I’m waiting till the functional content of these packages is settled/accepted,
and then I’ll write NEWS and manual entries.

> - There are many compiler warnings emitted when compiling Org with your patch

Oops, I keep on forgetting to check byte compilation. These should all be fixed now.

> The docstrings are missing in the above.

Docstrings have been added.

> I am not sure why, but the word fancy feels slightly annoying here.

Docsting rewritten.

> Since engraved is not entirely relying on LaTeX options, a lot of
> customisation is not mentioned in this docstring. AFAIU, color
> customisation is only possible by changing defcustoms from engrave-faces
> package.
>
> Another related note is what is going to happen in beamer export with
> dark background. The default face mapping in engrave-faces is using some
> kind of light theme, which may lose all the contrast on not-light
> background.

Modifying the style of engraved-faces-latex’s output is indeed done by
customising a engraved-faces variable. I don’t think we should attempt to do
anything further with this within Org.

To elaborate a bit, the generated LaTeX uses the styling information given in
`engrave-faces-preset-styles'. Changing this to use the current Emacs theme is as
simple as `(setq engrave-faces-preset-styles (engrave-faces-generate-preset))'.

> It feels that codebackground, codeborder, and EFD should be customizable
> by org-latex-engraved-options.

Hmm. I don’t think so. They are entirely self-contained within the preamble
variable. Should there be a nice existing `org-latex-user-colors' variable or
such, it would make a lot of sense to shove this there, but since no such
variable exists I’m not sure we can really do much better than just asking users
to modify `org-latex-engraved-preamble'.

> Docstring?

Added.

>> +    (message “Cannot engrave inline src block, `engrave-faces-latex’ is unavailible.”)
>
> Why message instead of error?

User errors are now thrown.

Thanks for the feedback!
Timothy

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Refactor-org-latex-src-block.patch --]
[-- Type: text/x-patch, Size: 15942 bytes --]

From d231437e2c9f96bf70520d9ddda810a95667fcdd Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 14:35:34 +0800
Subject: [PATCH 1/4] ox-latex: Refactor `org-latex-src-block'

* lisp/ox-latex.el (org-latex-src-block): Extract the per-format logic
from `org-latex-src-block' into new dedicated functions:
+ `org-latex-src-block--verbatim'
+ `org-latex-src-block--custom'
+ `org-latex-src-block--minted'
+ `org-latex-src-block--listings'
This makes `org-latex-src-block' much less monolithic, taking it from
175 lines to 30, and I find also makes it easier to understand.
---
 lisp/ox-latex.el | 339 ++++++++++++++++++++++++++---------------------
 1 file changed, 185 insertions(+), 154 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 841ad48bc..c2f728a1c 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2997,164 +2997,195 @@ (defun org-latex-src-block (src-block _contents info)
 	   (float (plist-get attributes :float))
 	   (listings (plist-get info :latex-listings)))
       (cond
-       ;; Case 1.  No source fontification.
        ((or (not lang) (not listings))
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
-                                (org-export-format-code-default src-block info))))
-          (cond ((string= "multicolumn" float)
-                 (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
-                         (plist-get info :latex-default-figure-position)
-                         (if caption-above-p caption-str "")
-                         verbatim
-                         (if caption-above-p "" caption-str)))
-                (caption (concat
-                          (if caption-above-p caption-str "")
-                          verbatim
-                          (if caption-above-p "" (concat "\n" caption-str))))
-                (t verbatim))))
-       ;; Case 2.  Custom environment.
+        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (custom-env
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (formatted-src (org-export-format-code-default src-block info)))
-          (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
-	      (format "\\begin{%s}\n%s\\end{%s}\n"
-		      custom-env
-		      (concat (and caption-above-p caption-str)
-			      formatted-src
-			      (and (not caption-above-p) caption-str))
-		      custom-env)
-	    (format-spec custom-env
-			 `((?s . ,formatted-src)
-			   (?c . ,caption)
-			   (?f . ,float)
-			   (?l . ,(org-latex--label src-block info))
-			   (?o . ,(or (plist-get attributes :options) "")))))))
-       ;; Case 3.  Use minted package.
+        (org-latex-src-block--custom src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
-	(let* ((caption-str (org-latex--caption/label-string src-block info))
-	       (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
-			      (plist-get info :latex-default-figure-position)))
-	       (float-env
-		(cond
-		 ((string= "multicolumn" float)
-		  (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 (caption
-		  (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 ((string= "t" float)
-		  (concat (format "\\begin{listing}[%s]\n"
-				  placement)
-			  "%s\n\\end{listing}"))
-		 (t "%s")))
-	       (options (plist-get info :latex-minted-options))
-	       (body
-		(format
-		 "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
-		 ;; Options.
-		 (concat
-		  (org-latex--make-option-string
-		   (if (or (not num-start) (assoc "linenos" options))
-		       options
-		     (append
-		      `(("linenos")
-			("firstnumber" ,(number-to-string (1+ num-start))))
-		      options)))
-		  (let ((local-options (plist-get attributes :options)))
-		    (and local-options (concat "," local-options))))
-		 ;; Language.
-		 (or (cadr (assq (intern lang)
-				 (plist-get info :latex-minted-langs)))
-		     (downcase lang))
-		 ;; Source code.
-		 (let* ((code-info (org-export-unravel-code src-block))
-			(max-width
-			 (apply 'max
-				(mapcar 'length
-					(org-split-string (car code-info)
-							  "\n")))))
-		   (org-export-format-code
-		    (car code-info)
-		    (lambda (loc _num ref)
-		      (concat
-		       loc
-		       (when ref
-			 ;; Ensure references are flushed to the right,
-			 ;; separated with 6 spaces from the widest line
-			 ;; of code.
-			 (concat (make-string (+ (- max-width (length loc)) 6)
-					      ?\s)
-				 (format "(%s)" ref)))))
-		    nil (and retain-labels (cdr code-info)))))))
-	  ;; Return value.
-	  (format float-env body)))
-       ;; Case 4.  Use listings package.
+        (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (t
-	(let ((lst-lang
-	       (or (cadr (assq (intern lang)
-			       (plist-get info :latex-listings-langs)))
-		   lang))
-	      (caption-str
-	       (when caption
-		 (let ((main (org-export-get-caption src-block))
-		       (secondary (org-export-get-caption src-block t)))
-		   (if (not secondary)
-		       (format "{%s}" (org-export-data main info))
-		     (format "{[%s]%s}"
-			     (org-export-data secondary info)
-			     (org-export-data main info))))))
-	      (lst-opt (plist-get info :latex-listings-options)))
-	  (concat
-	   ;; Options.
-	   (format
-	    "\\lstset{%s}\n"
-	    (concat
-	     (org-latex--make-option-string
-	      (append
-	       lst-opt
-	       (cond
-		((and (not float) (plist-member attributes :float)) nil)
-		((string= "multicolumn" float) '(("float" "*")))
-		((and float (not (assoc "float" lst-opt)))
-		 `(("float" ,(plist-get info :latex-default-figure-position)))))
-	       `(("language" ,lst-lang))
-	       (if label
-		   `(("label" ,(org-latex--label src-block info)))
-		 '(("label" " ")))
-	       (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
-	       `(("captionpos" ,(if caption-above-p "t" "b")))
-	       (cond ((assoc "numbers" lst-opt) nil)
-		     ((not num-start) '(("numbers" "none")))
-		     (t `(("firstnumber" ,(number-to-string (1+ num-start)))
-			  ("numbers" "left"))))))
-	     (let ((local-options (plist-get attributes :options)))
-	       (and local-options (concat "," local-options)))))
-	   ;; Source code.
-	   (format
-	    "\\begin{lstlisting}\n%s\\end{lstlisting}"
-	    (let* ((code-info (org-export-unravel-code src-block))
-		   (max-width
-		    (apply 'max
-			   (mapcar 'length
-				   (org-split-string (car code-info) "\n")))))
-	      (org-export-format-code
-	       (car code-info)
-	       (lambda (loc _num ref)
-		 (concat
-		  loc
-		  (when ref
-		    ;; Ensure references are flushed to the right,
-		    ;; separated with 6 spaces from the widest line of
-		    ;; code
-		    (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
-			    (format "(%s)" ref)))))
-	       nil (and retain-labels (cdr code-info))))))))))))
-
+        (org-latex-src-block--listings src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))))))
+
+(defun org-latex-src-block--verbatim
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels _attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
+                          (org-export-format-code-default src-block info))))
+    (cond ((string= "multicolumn" float)
+           (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
+                   (plist-get info :latex-default-figure-position)
+                   (if caption-above-p caption-str "")
+                   verbatim
+                   (if caption-above-p "" caption-str)))
+          (caption (concat
+                    (if caption-above-p caption-str "")
+                    verbatim
+                    (if caption-above-p "" (concat "\n" caption-str))))
+          (t verbatim))))
+
+(defun org-latex-src-block--custom
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels attributes float custom-env)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (formatted-src (org-export-format-code-default src-block info)))
+    (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
+        (format "\\begin{%s}\n%s\\end{%s}\n"
+                custom-env
+                (concat (and caption-above-p caption-str)
+                        formatted-src
+                        (and (not caption-above-p) caption-str))
+                custom-env)
+      (format-spec custom-env
+                   `((?s . ,formatted-src)
+                     (?c . ,caption)
+                     (?f . ,float)
+                     (?l . ,(org-latex--label src-block info))
+                     (?o . ,(or (plist-get attributes :options) "")))))))
+
+(defun org-latex-src-block--minted
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-minted-options))
+         (body
+          (format
+           "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (if (or (not num-start) (assoc "linenos" options))
+                 options
+               (append
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start))))
+                options)))
+            (let ((local-options (plist-get attributes :options)))
+              (and local-options (concat "," local-options))))
+           ;; Language.
+           (or (cadr (assq (intern lang)
+                           (plist-get info :latex-minted-langs)))
+               (downcase lang))
+           ;; Source code.
+           (let* ((code-info (org-export-unravel-code src-block))
+                  (max-width
+                   (apply 'max
+                          (mapcar 'length
+                                  (org-split-string (car code-info)
+                                                    "\n")))))
+             (org-export-format-code
+              (car code-info)
+              (lambda (loc _num ref)
+                (concat
+                 loc
+                 (when ref
+                   ;; Ensure references are flushed to the right,
+                   ;; separated with 6 spaces from the widest line
+                   ;; of code.
+                   (concat (make-string (+ (- max-width (length loc)) 6)
+                                        ?\s)
+                           (format "(%s)" ref)))))
+              nil (and retain-labels (cdr code-info)))))))
+    ;; Return value.
+    (format float-env body)))
+
+(defun org-latex-src-block--listings
+    (src-block info lang caption caption-above-p label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((lst-lang
+         (or (cadr (assq (intern lang)
+                         (plist-get info :latex-listings-langs)))
+             lang))
+        (caption-str
+         (when caption
+           (let ((main (org-export-get-caption src-block))
+                 (secondary (org-export-get-caption src-block t)))
+             (if (not secondary)
+                 (format "{%s}" (org-export-data main info))
+               (format "{[%s]%s}"
+                       (org-export-data secondary info)
+                       (org-export-data main info))))))
+        (lst-opt (plist-get info :latex-listings-options)))
+    (concat
+     ;; Options.
+     (format
+      "\\lstset{%s}\n"
+      (concat
+       (org-latex--make-option-string
+        (append
+         lst-opt
+         (cond
+          ((and (not float) (plist-member attributes :float)) nil)
+          ((string= "multicolumn" float) '(("float" "*")))
+          ((and float (not (assoc "float" lst-opt)))
+           `(("float" ,(plist-get info :latex-default-figure-position)))))
+         `(("language" ,lst-lang))
+         (if label
+             `(("label" ,(org-latex--label src-block info)))
+           '(("label" " ")))
+         (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
+         `(("captionpos" ,(if caption-above-p "t" "b")))
+         (cond ((assoc "numbers" lst-opt) nil)
+               ((not num-start) '(("numbers" "none")))
+               (t `(("firstnumber" ,(number-to-string (1+ num-start)))
+                    ("numbers" "left"))))))
+       (let ((local-options (plist-get attributes :options)))
+         (and local-options (concat "," local-options)))))
+     ;; Source code.
+     (format
+      "\\begin{lstlisting}\n%s\\end{lstlisting}"
+      (let* ((code-info (org-export-unravel-code src-block))
+             (max-width
+              (apply 'max
+                     (mapcar 'length
+                             (org-split-string (car code-info) "\n")))))
+        (org-export-format-code
+         (car code-info)
+         (lambda (loc _num ref)
+           (concat
+            loc
+            (when ref
+              ;; Ensure references are flushed to the right,
+              ;; separated with 6 spaces from the widest line of
+              ;; code
+              (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
+                      (format "(%s)" ref)))))
+         nil (and retain-labels (cdr code-info))))))))
 
 ;;;; Statistics Cookie
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-ox-latex-Refactor-org-latex-inline-src-block.patch --]
[-- Type: text/x-patch, Size: 4020 bytes --]

From ea5d116b06326be46e3053e6ded26d5b8b0638d9 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 18:53:10 +0800
Subject: [PATCH 2/4] ox-latex: Refactor `org-latex-inline-src-block'

* lisp/ox-latex.el (org-latex-inline-src-block,
org-latex-inline-src-block--minted,
org-latex-inline-src-block--listings): Extract the minted and listings
specific logic out of `org-latex-inline-src-block` into the new
functions `org-latex-inline-src-block--minted` and
`org-latex-inline-src-block--listings`.
---
 lisp/ox-latex.el | 62 +++++++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index c2f728a1c..2b732cf16 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2127,36 +2127,38 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
   "Transcode an INLINE-SRC-BLOCK element from Org to LaTeX.
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
-  (let* ((code (org-element-property :value inline-src-block))
-	 (separator (org-latex--find-verb-separator code)))
-    (cl-case (plist-get info :latex-listings)
-      ;; Do not use a special package: transcode it verbatim, as code.
-      ((nil) (org-latex--text-markup code 'code info))
-      ;; Use minted package.
-      (minted
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (mint-lang (or (cadr (assq (intern org-lang)
-					 (plist-get info :latex-minted-langs)))
-			     (downcase org-lang)))
-	      (options (org-latex--make-option-string
-			(plist-get info :latex-minted-options))))
-	 (format "\\mintinline%s{%s}{%s}"
-		 (if (string= options "") "" (format "[%s]" options))
-		 mint-lang
-		 code)))
-      ;; Use listings package.
-      (otherwise
-       ;; Maybe translate language's name.
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (lst-lang (or (cadr (assq (intern org-lang)
-					(plist-get info :latex-listings-langs)))
-			    org-lang))
-	      (options (org-latex--make-option-string
-			(append (plist-get info :latex-listings-options)
-				`(("language" ,lst-lang))))))
-	 (concat (format "\\lstinline[%s]" options)
-		 separator code separator))))))
-
+  (let ((code (org-element-property :value inline-src-block))
+        (lang (org-element-property :language inline-src-block)))
+    (pcase (plist-get info :latex-listings)
+      ('nil (org-latex--text-markup code 'code info))
+      ('minted (org-latex-inline-src-block--minted info code lang))
+      (_ (org-latex-inline-src-block--listings info code lang)))))
+
+(defun org-latex-inline-src-block--minted (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using minted.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let ((mint-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-minted-langs)))
+                       (downcase org-lang)))
+        (options (org-latex--make-option-string
+                  (plist-get info :latex-minted-options))))
+    (format "\\mintinline%s{%s}{%s}"
+            (if (string= options "") "" (format "[%s]" options))
+            mint-lang
+            code)))
+
+(defun org-latex-inline-src-block--listings (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (let* ((lst-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-listings-langs)))
+                       lang))
+         (separator (org-latex--find-verb-separator code))
+         (options (org-latex--make-option-string
+                   (append (plist-get info :latex-listings-options)
+                           `(("language" ,lst-lang))))))
+    (concat (format "\\lstinline[%s]" options)
+            separator code separator)))
 
 ;;;; Inlinetask
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-ox-latex-More-versitile-option-construction.patch --]
[-- Type: text/x-patch, Size: 4116 bytes --]

From aa0a9dafab7a7246e2855a2257d4c156eb48752c Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 23:31:59 +0800
Subject: [PATCH 3/4] ox-latex: More versitile option construction

* lisp/ox-latex.el (org-latex--make-option-string): Support a custom
option seperator string.

(org-latex--make-option-string, org-latex-minted-options,
org-latex-listings-options): The first line of the docstrings for
`org-latex-minted-options` and `org-latex-listings-options` describe the
variables as "association lists", yet `org-latex--make-option-string`
does not handle association lists and an example of two-value lists is
provided.  To make the behaviour match the docstring,
`org-latex--make-option-string` is modified to work with either a list
two-value lists or an association list, and the examples in
`org-latex-minted-options` and `org-latex-listings-options` updated
accordingly.
---
 lisp/ox-latex.el | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 2b732cf16..4181db175 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1006,12 +1006,16 @@ (defcustom org-latex-listings-options nil
 
 These options are supplied as a comma-separated list to the
 \\lstset command.  Each element of the association list should be
-a list containing two strings: the name of the option, and the
-value.  For example,
+a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-listings-options
     \\='((\"basicstyle\" \"\\\\small\")
       (\"keywordstyle\" \"\\\\color{black}\\\\bfseries\\\\underbar\")))
+  ; or
+  (setq org-latex-listings-options
+    \\='((\"basicstyle\" . \"\\\\small\")
+      (\"keywordstyle\" . \"\\\\color{black}\\\\bfseries\\\\underbar\")))
 
 will typeset the code in a small size font with underlined, bold
 black keywords.
@@ -1059,11 +1063,14 @@ (defcustom org-latex-minted-options nil
 
 These options are supplied within square brackets in
 \\begin{minted} environments.  Each element of the alist should
-be a list containing two strings: the name of the option, and the
-value.  For example,
+be a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-minted-options
     \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-minted-options
+    \\='((\"bgcolor\" . \"bg\") (\"frame\" . \"lines\")))
 
 will result in source blocks being exported with
 
@@ -1506,21 +1513,24 @@ (defun org-latex--find-verb-separator (s)
 	     when (not (string-match (regexp-quote (char-to-string c)) s))
 	     return (char-to-string c))))
 
-(defun org-latex--make-option-string (options)
+(defun org-latex--make-option-string (options &optional seperator)
   "Return a comma separated string of keywords and values.
 OPTIONS is an alist where the key is the options keyword as
 a string, and the value a list containing the keyword value, or
 nil."
   (mapconcat (lambda (pair)
-	       (pcase-let ((`(,keyword ,value) pair))
-		 (concat keyword
-			 (and (> (length value) 0)
-			      (concat "="
-                                      (if (string-match-p (rx (any "[]")) value)
-                                          (format "{%s}" value)
-                                        value))))))
-	     options
-	     ","))
+               (let ((keyword (car pair))
+                     (value (pcase (cdr pair)
+                              ((pred stringp) (cdr pair))
+                              ((pred consp) (cadr pair)))))
+                 (concat keyword
+                         (when value
+                           (concat "="
+                                   (if (string-match-p (rx (any "[]")) value)
+                                       (format "{%s}" value)
+                                     value))))))
+             options
+             (or seperator ",")))
 
 (defun org-latex--wrap-label (element output info)
   "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-ox-latex-Introduce-engraved-code-highlighting.patch --]
[-- Type: text/x-patch, Size: 17464 bytes --]

From 90849f3986cc709c1d01ec9f204a7eb8b940cd27 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 20:04:12 +0800
Subject: [PATCH 4/4] ox-latex: Introduce "engraved" code highlighting

* lisp/ox-latex.el (org-latex-src-block, org-latex-src-block--engraved,
org-latex-inline-src-block, org-latex-inline-src-block--engraved,
org-latex-template, org-latex-listings): Make use of the engraved-faces
package (available on ELPA) to provide an alternative LaTeX code
highlighting backend which functions similarly to htmlize.el for HTML
exports.

(org-latex-engraved-preamble, org-latex-engraved-options): Introduce
variables to construct the preamble for engraved code blocks.

* lisp/ox-beamer.el (org-beamer-template): Modify to add engrave-faces
preamble when applicable.
---
 lisp/ox-beamer.el |   9 ++
 lisp/ox-latex.el  | 273 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 272 insertions(+), 10 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 6be73c91e..73bd95539 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -857,6 +857,15 @@ (defun org-beamer-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 4181db175..831509a26 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -37,6 +37,8 @@ (defvar org-latex-default-packages-alist)
 (defvar org-latex-packages-alist)
 (defvar orgtbl-exp-regexp)
 
+(declare-function engrave-faces-latex-gen-preamble "ext:engrave-faces-latex")
+(declare-function engrave-faces-latex-buffer "ext:engrave-faces-latex")
 
 \f
 ;;; Define Back-End
@@ -125,6 +127,8 @@ (org-export-define-backend 'latex
     (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
     (:latex-default-table-mode nil nil org-latex-default-table-mode)
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
+    (:latex-engraved-options nil nil org-latex-engraved-options)
+    (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -937,22 +941,48 @@ (defcustom org-latex-listings nil
   "Non-nil means export source code using the listings package.
 
 This package will fontify source code, possibly even with color.
-If you want to use this, you also need to make LaTeX use the
-listings package, and if you want to have color, the color
-package.  Just add these to `org-latex-packages-alist', for
-example using customize, or with something like:
+There are four implementations of this functionality you may
+choose from (ordered from least to most capable):
+1. Verbatim (nil)
+2. Listings (t)
+3. Minted (minted)
+4. Engraved (engraved)
+
+The first two options provide basic syntax
+highlighting (listings), or none at all (verbatim).
+
+When using listings, you also need to make use of the LaTeX
+\"listings\" package. The \"color\" package is also needed if you
+would like color too.  These can simply be added to
+`org-latex-packages-alist', using customise or something like:
 
   (require \\='ox-latex)
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\"))
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\"))
 
-Alternatively,
+There are two options for more comprehensive fontification. The
+first can be set with,
+
+  (setq org-latex-listings \\='engraved)
+
+which causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the engrave-faces
+package (availible from ELPA), and the fvextra LaTeX package be
+installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the tcolorbox LaTeX package in
+addition to fvextra.
+
+The second more comprehensive option can be used with,
 
   (setq org-latex-listings \\='minted)
 
-causes source code to be exported using the minted package as
-opposed to listings.  If you want to use minted, you need to add
-the minted package to `org-latex-packages-alist', for example
+which causes source code to be exported using the minted package
+as opposed to listings.  If you want to use minted, you need to
+add the minted package to `org-latex-packages-alist', for example
 using customize, or with
 
   (require \\='ox-latex)
@@ -971,8 +1001,9 @@ (defcustom org-latex-listings nil
   :type '(choice
 	  (const :tag "Use listings" t)
 	  (const :tag "Use minted" minted)
+	  (const :tag "Use engrave-faces-latex" engraved)
 	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted))))
+  :safe (lambda (s) (memq s '(t nil minted engraved))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1142,6 +1173,124 @@ (defcustom org-latex-custom-lang-environments nil
   :version "26.1"
   :package-version '(Org . "9.0"))
 
+(defcustom org-latex-engraved-preamble
+  "\\usepackage{fvextra}
+
+[FVEXTRA-SETUP]
+
+\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
+
+\\usepackage{xcolor}
+
+\\providecolor{codebackground}{HTML}{f7f7f7}
+\\providecolor{codeborder}{HTML}{f0f0f0}
+\\providecolor{EFD}{HTML}{28292e}
+
+% TODO have code boxes keep line vertical alignment
+\\usepackage[breakable,xparse]{tcolorbox}
+\\DeclareTColorBox[]{Code}{o}%
+{colback=codebackground, colframe=codeborder,
+  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
+  colupper=EFD,
+  IfNoValueTF={#1}%
+  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
+    boxrule=0.5pt, left=2pt}%
+  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
+    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
+  right=2pt, top=1pt, bottom=0.5pt,
+  breakable}"
+  "Preamble content injected when using engrave-faces-latex for source blocks.
+This is relevant when `org-latex-listings' is set to `engraved'.
+
+There is quite a lot of flexibility in what this preamble can be, as long as it:
+- Loads the fvextra package.
+- Loads the package xcolor (if it is not already loader elsewhere).
+- Defines a \"Code\" environment (note the capital C), which can be
+  later used to wrap \"Verbatim\" environments (provided by fvextra).
+
+A macro-like placeholder is used to set fvextra's defaults according to
+`org-latex-engraved-options':
+
+  [FVEXTRA-SETUP]
+
+In the default value the color \"EFD\" is provided as this is the
+foreground colour provided by engrave-faces-latex.  When there
+are example/fixed-width blocks only, the engraved generated
+preamble is not included, and so it is provided so we may use it
+anyway."
+  :group 'org-export-latex
+  :type 'string
+  :package-version '(Org . "9.6"))
+
+(defcustom org-latex-engraved-options
+  '(("commandchars" . "\\\\\\{\\}")
+    ("highlightcolor" . "white!95!black!80!blue")
+    ("breaklines" . "true")
+    ("breaksymbol" . "\\color{white!60!black}\\tiny\\ensuremath{\\hookrightarrow}"))
+  "Association list of options for the latex fvextra package when engraving code.
+
+These options are set using \\fvset{...} in the preamble of the
+LaTeX export.  Each element of the alist should be a list or cons
+cell containing two strings: the name of the option, and the
+value.  For example,
+
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" \"green\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-engraved-options
+    \\='((\"highlightcolor\" . \"green\") (\"frame\" . \"lines\")))
+
+will result in the following LaTeX in the preamble
+
+\\fvset{%
+  bgcolor=bg,
+  frame=lines}
+
+This will affect all fvextra environments.  Note that the same
+options will be applied to all blocks.  If you need
+block-specific options, you may use the following syntax:
+
+  #+ATTR_LATEX: :options key1=value1,key2=value2
+  #+BEGIN_SRC <LANG>
+  ...
+  #+END_SRC"
+  :group 'org-export-latex
+  :type '(alist :key-type (string :tag "option")
+                :value-type (string :tag "value")))
+
+(defun org-latex-generate-engraved-preamble (info syntax-colours-p)
+  "Generate the preamble to setup engraved code.
+The result is constructed from `org-latex-engraved-preamble' and
+`org-latex-engraved-options'."
+  (let* ((engraved-options
+          (plist-get info :latex-engraved-options))
+         (engraved-preamble-template
+          (plist-get info :latex-engraved-preamble))
+         (engraved-preamble
+          (if (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?"
+                            engraved-preamble)
+              (replace-match
+               (concat
+                "\\fvset{%\n  "
+                (org-latex--make-option-string engraved-options ",\n  ")
+                "}\n")
+               t t
+               engraved-preamble-template)
+            engraved-preamble-template)))
+    (if syntax-colours-p
+        (concat
+         "\n% Setup for code blocks [1/2]\n\n"
+         engraved-preamble
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         (if (require 'engrave-faces-latex nil t)
+             (engrave-faces-latex-gen-preamble)
+           (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
+           "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
+         "\n")
+      (concat
+       "\n% Setup for code blocks\n\n"
+       engraved-preamble
+       "\n"))))
 
 ;;;; Compilation
 
@@ -1756,6 +1905,15 @@ (defun org-latex-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
             (format-spec template spec)))
+     ;; engrave-faces-latex preamble
+     (when (eq org-latex-listings 'engraved)
+       (let ((src-p (org-element-map (plist-get info :parse-tree)
+                        '(src-block inline-src-block) #'identity))
+             (fixedw-p
+              (org-element-map (plist-get info :parse-tree)
+                  '(example-block fixed-width) #'identity)))
+         (when (or src-p fixedw-p)
+           (org-latex-generate-engraved-preamble info src-p))))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
@@ -2142,6 +2300,7 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
     (pcase (plist-get info :latex-listings)
       ('nil (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
+      ('engraved (org-latex-inline-src-block--engraved info code lang))
       (_ (org-latex-inline-src-block--listings info code lang)))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
@@ -2149,7 +2308,7 @@ (defun org-latex-inline-src-block--minted (info code lang)
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
   (let ((mint-lang (or (cadr (assq (intern lang)
                                    (plist-get info :latex-minted-langs)))
-                       (downcase org-lang)))
+                       (downcase lang)))
         (options (org-latex--make-option-string
                   (plist-get info :latex-minted-options))))
     (format "\\mintinline%s{%s}{%s}"
@@ -2157,6 +2316,24 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
+(defun org-latex-inline-src-block--engraved (info code lang)
+  "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
+INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
+  (if (require 'engrave-faces-latex nil t)
+      (let (engraved-buffer engraved-code)
+        (setq engraved-buffer
+              (with-temp-buffer
+                (insert code)
+                (funcall (org-src-get-lang-mode lang))
+                (engrave-faces-latex-buffer)))
+        (setq engraved-code
+              (with-current-buffer engraved-buffer
+                (buffer-string)))
+        (kill-buffer engraved-buffer)
+        (format "\\Verb{%s}"
+                engraved-code))
+    (user-error "Cannot engrave inline src block, `engrave-faces-latex' is unavailible.")))
+
 (defun org-latex-inline-src-block--listings (info code lang)
   "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
 INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
@@ -3017,6 +3194,9 @@ (defun org-latex-src-block (src-block _contents info)
                                      num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
         (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float))
+       ((eq listings 'engraved)
+        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
                                        num-start retain-labels attributes float))
        (t
         (org-latex-src-block--listings src-block info lang caption caption-above-p label
@@ -3133,6 +3313,79 @@ (defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
+(defun org-latex-src-block--engraved
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (if (require 'engrave-faces-latex nil t)
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-engraved-options))
+         (content-buffer
+          (with-temp-buffer
+            (insert
+             (let* ((code-info (org-export-unravel-code src-block))
+                    (max-width
+                     (apply 'max
+                            (mapcar 'length
+                                    (org-split-string (car code-info)
+                                                      "\n")))))
+               (org-export-format-code
+                (car code-info)
+                (lambda (loc _num ref)
+                  (concat
+                   loc
+                   (when ref
+                     ;; Ensure references are flushed to the right,
+                     ;; separated with 6 spaces from the widest line
+                     ;; of code.
+                     (concat (make-string (+ (- max-width (length loc)) 6)
+                                          ?\s)
+                             (format "(%s)" ref)))))
+                nil (and retain-labels (cdr code-info)))))
+            (funcall (org-src-get-lang-mode lang))
+            (engrave-faces-latex-buffer)))
+         (content
+          (with-current-buffer content-buffer
+            (buffer-string)))
+         (body
+          (format
+           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (append
+              (when (and num-start (not (assoc "linenos" options)))
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start)))))
+              (let ((local-options (plist-get attributes :options)))
+                (and local-options (list local-options))))))
+           content)))
+    (kill-buffer content-buffer)
+    ;; Return value.
+    (format float-env body))
+  (user-error "Cannot engrave src block, `engrave-faces-latex' is unavailible.")))
+
 (defun org-latex-src-block--listings
     (src-block info lang caption caption-above-p label
                num-start retain-labels attributes float)
-- 
2.35.3


^ permalink raw reply related	[relevance 4%]

* [PATCH] New LaTeX code export option: engraved
@ 2022-05-04 15:59  5% Timothy
    0 siblings, 1 reply; 200+ results
From: Timothy @ 2022-05-04 15:59 UTC (permalink / raw)
  To: emacs-orgmode, Daniel Fleischer, Nicolas Goaziou


[-- Attachment #1.1: Type: text/plain, Size: 3432 bytes --]

Hi All,

I’ve been fairly busy as of late (hence my recent silence on this ML), however I
have a patchset that’s been in the works for a while that I’ve finally polished
up.

Short version: It adds a new (superior) option for exporting code blocks with
syntax highlighting to LaTeX.

The long version follows.

Currently there are four options for exporting code to LaTeX (ordered by
complexity/quality).
1. Verbatim, which simply includes the code unstyled
2. Custom, which puts the code in an enviroment of your choice
3. Listings, which uses the LaTeX package by this name. This is quick, but
   exceedingly basic.
4. Minted, which uses the LaTeX package by this name. This is slow, but produces
   better results than Listings

This patchset accomplishes two things:
1. It refactors the overly large `org-latex-src-block' function, and makes a few
   other improvements to pre-existing code
2. It adds a new option for exporting code, named (you guessed it!) “engraved”

What is this new option, and why do we want it?

About a year ago I started work on a package that generalises the functionality
of `htmlize.el', termed `engrave-faces'
(<https://elpa.gnu.org/packages/engrave-faces.html>). It provides the ability to
extract font-lock information and export it to a number of formats: html, ansi,
and (crucially) LaTeX! Since the LaTeX export is built on the `fvextra' (LaTeX)
package (like pygments), the vast majority of the Minted options you’re used to
just carry over.

This allows for a result that is, I think, straight up better than all the
pre-existing options. For starters, you can now apply syntax highlighting to any
language you have a major mode for.

There are a number of optimisations unattempted, but it already significantly
outperforms Minted. Here are some timings from my `config.org':

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 LaTeX code backend  Compile time  Overhead  Overhead ratio 
────────────────────────────────────────────────────────────
 verbatim            12 s          0                    0.0 
 lstlistings         15 s          3 s                  0.2 
 Engrave             34 s          22 s                 1.8 
 Pygments (Minted)   184 s         172 s               14.3 
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Compared to Minted, we also no longer have to install `pygments' or pass the
`--shelll-escape' flag to LaTeX to generate passable code blocks.

Having an all-emacs system also allows for some nifty things, like having entire
documents/presentations based on your Emacs theme (see
<https://github.com/tecosaur/ox-chameleon>). Demo images: <https://0x0.st/oAl1.png>,
<https://0x0.st/oAle.png>.

Here are some more screenshots to see what the result can look like in practice:
• <https://0x0.st/oAl2.png>
• <https://0x0.st/oAl_.png>
• <https://0x0.st/oAlL.png>

So, please take a look at the patches, give this a whirl, and let me know what
you think! 😀

All the best,
Timothy

[-- Attachment #1.2: Type: text/html, Size: 14197 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-latex-Refactor-org-latex-src-block.patch --]
[-- Type: text/x-patch, Size: 15943 bytes --]

From 87872cc8f2fb1da1a03dc4aadfbd4af6541d8c13 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 14:35:34 +0800
Subject: [PATCH 1/4] ox-latex: Refactor `org-latex-src-block'

* lisp/ox-latex.el (org-latex-src-block): Extract the per-format logic
from `org-latex-src-block' into new dedicated functions:
+ `org-latex-src-block--verbatim'
+ `org-latex-src-block--custom'
+ `org-latex-src-block--minted'
+ `org-latex-src-block--listings'
This makes `org-latex-src-block' much less monolithic, taking it from
175 lines to 30, and I find also makes it easier to understand.
---
 lisp/ox-latex.el | 339 ++++++++++++++++++++++++++---------------------
 1 file changed, 185 insertions(+), 154 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 841ad48bc..63855d2f6 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2997,164 +2997,195 @@ (defun org-latex-src-block (src-block _contents info)
 	   (float (plist-get attributes :float))
 	   (listings (plist-get info :latex-listings)))
       (cond
-       ;; Case 1.  No source fontification.
        ((or (not lang) (not listings))
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
-                                (org-export-format-code-default src-block info))))
-          (cond ((string= "multicolumn" float)
-                 (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
-                         (plist-get info :latex-default-figure-position)
-                         (if caption-above-p caption-str "")
-                         verbatim
-                         (if caption-above-p "" caption-str)))
-                (caption (concat
-                          (if caption-above-p caption-str "")
-                          verbatim
-                          (if caption-above-p "" (concat "\n" caption-str))))
-                (t verbatim))))
-       ;; Case 2.  Custom environment.
+        (org-latex-src-block--verbatim src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (custom-env
-	(let ((caption-str (org-latex--caption/label-string src-block info))
-              (formatted-src (org-export-format-code-default src-block info)))
-          (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
-	      (format "\\begin{%s}\n%s\\end{%s}\n"
-		      custom-env
-		      (concat (and caption-above-p caption-str)
-			      formatted-src
-			      (and (not caption-above-p) caption-str))
-		      custom-env)
-	    (format-spec custom-env
-			 `((?s . ,formatted-src)
-			   (?c . ,caption)
-			   (?f . ,float)
-			   (?l . ,(org-latex--label src-block info))
-			   (?o . ,(or (plist-get attributes :options) "")))))))
-       ;; Case 3.  Use minted package.
+        (org-latex-src-block--custom src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
-	(let* ((caption-str (org-latex--caption/label-string src-block info))
-	       (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
-			      (plist-get info :latex-default-figure-position)))
-	       (float-env
-		(cond
-		 ((string= "multicolumn" float)
-		  (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 (caption
-		  (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
-			  placement
-			  (if caption-above-p caption-str "")
-			  (if caption-above-p "" caption-str)))
-		 ((string= "t" float)
-		  (concat (format "\\begin{listing}[%s]\n"
-				  placement)
-			  "%s\n\\end{listing}"))
-		 (t "%s")))
-	       (options (plist-get info :latex-minted-options))
-	       (body
-		(format
-		 "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
-		 ;; Options.
-		 (concat
-		  (org-latex--make-option-string
-		   (if (or (not num-start) (assoc "linenos" options))
-		       options
-		     (append
-		      `(("linenos")
-			("firstnumber" ,(number-to-string (1+ num-start))))
-		      options)))
-		  (let ((local-options (plist-get attributes :options)))
-		    (and local-options (concat "," local-options))))
-		 ;; Language.
-		 (or (cadr (assq (intern lang)
-				 (plist-get info :latex-minted-langs)))
-		     (downcase lang))
-		 ;; Source code.
-		 (let* ((code-info (org-export-unravel-code src-block))
-			(max-width
-			 (apply 'max
-				(mapcar 'length
-					(org-split-string (car code-info)
-							  "\n")))))
-		   (org-export-format-code
-		    (car code-info)
-		    (lambda (loc _num ref)
-		      (concat
-		       loc
-		       (when ref
-			 ;; Ensure references are flushed to the right,
-			 ;; separated with 6 spaces from the widest line
-			 ;; of code.
-			 (concat (make-string (+ (- max-width (length loc)) 6)
-					      ?\s)
-				 (format "(%s)" ref)))))
-		    nil (and retain-labels (cdr code-info)))))))
-	  ;; Return value.
-	  (format float-env body)))
-       ;; Case 4.  Use listings package.
+        (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))
        (t
-	(let ((lst-lang
-	       (or (cadr (assq (intern lang)
-			       (plist-get info :latex-listings-langs)))
-		   lang))
-	      (caption-str
-	       (when caption
-		 (let ((main (org-export-get-caption src-block))
-		       (secondary (org-export-get-caption src-block t)))
-		   (if (not secondary)
-		       (format "{%s}" (org-export-data main info))
-		     (format "{[%s]%s}"
-			     (org-export-data secondary info)
-			     (org-export-data main info))))))
-	      (lst-opt (plist-get info :latex-listings-options)))
-	  (concat
-	   ;; Options.
-	   (format
-	    "\\lstset{%s}\n"
-	    (concat
-	     (org-latex--make-option-string
-	      (append
-	       lst-opt
-	       (cond
-		((and (not float) (plist-member attributes :float)) nil)
-		((string= "multicolumn" float) '(("float" "*")))
-		((and float (not (assoc "float" lst-opt)))
-		 `(("float" ,(plist-get info :latex-default-figure-position)))))
-	       `(("language" ,lst-lang))
-	       (if label
-		   `(("label" ,(org-latex--label src-block info)))
-		 '(("label" " ")))
-	       (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
-	       `(("captionpos" ,(if caption-above-p "t" "b")))
-	       (cond ((assoc "numbers" lst-opt) nil)
-		     ((not num-start) '(("numbers" "none")))
-		     (t `(("firstnumber" ,(number-to-string (1+ num-start)))
-			  ("numbers" "left"))))))
-	     (let ((local-options (plist-get attributes :options)))
-	       (and local-options (concat "," local-options)))))
-	   ;; Source code.
-	   (format
-	    "\\begin{lstlisting}\n%s\\end{lstlisting}"
-	    (let* ((code-info (org-export-unravel-code src-block))
-		   (max-width
-		    (apply 'max
-			   (mapcar 'length
-				   (org-split-string (car code-info) "\n")))))
-	      (org-export-format-code
-	       (car code-info)
-	       (lambda (loc _num ref)
-		 (concat
-		  loc
-		  (when ref
-		    ;; Ensure references are flushed to the right,
-		    ;; separated with 6 spaces from the widest line of
-		    ;; code
-		    (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
-			    (format "(%s)" ref)))))
-	       nil (and retain-labels (cdr code-info))))))))))))
-
+        (org-latex-src-block--listings src-block info lang caption caption-above-p label
+                                       num-start retain-labels attributes float))))))
+
+(defun org-latex-src-block--verbatim
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels _attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
+                          (org-export-format-code-default src-block info))))
+    (cond ((string= "multicolumn" float)
+           (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
+                   (plist-get info :latex-default-figure-position)
+                   (if caption-above-p caption-str "")
+                   verbatim
+                   (if caption-above-p "" caption-str)))
+          (caption (concat
+                    (if caption-above-p caption-str "")
+                    verbatim
+                    (if caption-above-p "" (concat "\n" caption-str))))
+          (t verbatim))))
+
+(defun org-latex-src-block--custom
+    (src-block info _lang caption caption-above-p _label
+               _num-start _retain-labels attributes float custom-env)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((caption-str (org-latex--caption/label-string src-block info))
+        (formatted-src (org-export-format-code-default src-block info)))
+    (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
+        (format "\\begin{%s}\n%s\\end{%s}\n"
+                custom-env
+                (concat (and caption-above-p caption-str)
+                        formatted-src
+                        (and (not caption-above-p) caption-str))
+                custom-env)
+      (format-spec custom-env
+                   `((?s . ,formatted-src)
+                     (?c . ,caption)
+                     (?f . ,float)
+                     (?l . ,(org-latex--label src-block info))
+                     (?o . ,(or (plist-get attributes :options) "")))))))
+
+(defun org-latex-src-block--minted
+    (src-block info _lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-minted-options))
+         (body
+          (format
+           "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (if (or (not num-start) (assoc "linenos" options))
+                 options
+               (append
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start))))
+                options)))
+            (let ((local-options (plist-get attributes :options)))
+              (and local-options (concat "," local-options))))
+           ;; Language.
+           (or (cadr (assq (intern lang)
+                           (plist-get info :latex-minted-langs)))
+               (downcase lang))
+           ;; Source code.
+           (let* ((code-info (org-export-unravel-code src-block))
+                  (max-width
+                   (apply 'max
+                          (mapcar 'length
+                                  (org-split-string (car code-info)
+                                                    "\n")))))
+             (org-export-format-code
+              (car code-info)
+              (lambda (loc _num ref)
+                (concat
+                 loc
+                 (when ref
+                   ;; Ensure references are flushed to the right,
+                   ;; separated with 6 spaces from the widest line
+                   ;; of code.
+                   (concat (make-string (+ (- max-width (length loc)) 6)
+                                        ?\s)
+                           (format "(%s)" ref)))))
+              nil (and retain-labels (cdr code-info)))))))
+    ;; Return value.
+    (format float-env body)))
+
+(defun org-latex-src-block--listings
+    (src-block info lang caption caption-above-p label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (let ((lst-lang
+         (or (cadr (assq (intern lang)
+                         (plist-get info :latex-listings-langs)))
+             lang))
+        (caption-str
+         (when caption
+           (let ((main (org-export-get-caption src-block))
+                 (secondary (org-export-get-caption src-block t)))
+             (if (not secondary)
+                 (format "{%s}" (org-export-data main info))
+               (format "{[%s]%s}"
+                       (org-export-data secondary info)
+                       (org-export-data main info))))))
+        (lst-opt (plist-get info :latex-listings-options)))
+    (concat
+     ;; Options.
+     (format
+      "\\lstset{%s}\n"
+      (concat
+       (org-latex--make-option-string
+        (append
+         lst-opt
+         (cond
+          ((and (not float) (plist-member attributes :float)) nil)
+          ((string= "multicolumn" float) '(("float" "*")))
+          ((and float (not (assoc "float" lst-opt)))
+           `(("float" ,(plist-get info :latex-default-figure-position)))))
+         `(("language" ,lst-lang))
+         (if label
+             `(("label" ,(org-latex--label src-block info)))
+           '(("label" " ")))
+         (if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
+         `(("captionpos" ,(if caption-above-p "t" "b")))
+         (cond ((assoc "numbers" lst-opt) nil)
+               ((not num-start) '(("numbers" "none")))
+               (t `(("firstnumber" ,(number-to-string (1+ num-start)))
+                    ("numbers" "left"))))))
+       (let ((local-options (plist-get attributes :options)))
+         (and local-options (concat "," local-options)))))
+     ;; Source code.
+     (format
+      "\\begin{lstlisting}\n%s\\end{lstlisting}"
+      (let* ((code-info (org-export-unravel-code src-block))
+             (max-width
+              (apply 'max
+                     (mapcar 'length
+                             (org-split-string (car code-info) "\n")))))
+        (org-export-format-code
+         (car code-info)
+         (lambda (loc _num ref)
+           (concat
+            loc
+            (when ref
+              ;; Ensure references are flushed to the right,
+              ;; separated with 6 spaces from the widest line of
+              ;; code
+              (concat (make-string (+ (- max-width (length loc)) 6) ?\s)
+                      (format "(%s)" ref)))))
+         nil (and retain-labels (cdr code-info))))))))
 
 ;;;; Statistics Cookie
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-ox-latex-Refactor-org-latex-inline-src-block.patch --]
[-- Type: text/x-patch, Size: 3727 bytes --]

From a4d833418c3e2f0a8f365b92c01c091f75b6482d Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 18:53:10 +0800
Subject: [PATCH 2/4] ox-latex: Refactor `org-latex-inline-src-block'

* lisp/ox-latex.el (org-latex-inline-src-block,
org-latex-inline-src-block--minted,
org-latex-inline-src-block--listings): Extract the minted and listings
specific logic out of `org-latex-inline-src-block` into the new
functions `org-latex-inline-src-block--minted` and
`org-latex-inline-src-block--listings`.
---
 lisp/ox-latex.el | 58 +++++++++++++++++++++++-------------------------
 1 file changed, 28 insertions(+), 30 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 63855d2f6..ed66a51c0 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -2127,36 +2127,34 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
   "Transcode an INLINE-SRC-BLOCK element from Org to LaTeX.
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
-  (let* ((code (org-element-property :value inline-src-block))
-	 (separator (org-latex--find-verb-separator code)))
-    (cl-case (plist-get info :latex-listings)
-      ;; Do not use a special package: transcode it verbatim, as code.
-      ((nil) (org-latex--text-markup code 'code info))
-      ;; Use minted package.
-      (minted
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (mint-lang (or (cadr (assq (intern org-lang)
-					 (plist-get info :latex-minted-langs)))
-			     (downcase org-lang)))
-	      (options (org-latex--make-option-string
-			(plist-get info :latex-minted-options))))
-	 (format "\\mintinline%s{%s}{%s}"
-		 (if (string= options "") "" (format "[%s]" options))
-		 mint-lang
-		 code)))
-      ;; Use listings package.
-      (otherwise
-       ;; Maybe translate language's name.
-       (let* ((org-lang (org-element-property :language inline-src-block))
-	      (lst-lang (or (cadr (assq (intern org-lang)
-					(plist-get info :latex-listings-langs)))
-			    org-lang))
-	      (options (org-latex--make-option-string
-			(append (plist-get info :latex-listings-options)
-				`(("language" ,lst-lang))))))
-	 (concat (format "\\lstinline[%s]" options)
-		 separator code separator))))))
-
+  (let ((code (org-element-property :value inline-src-block))
+        (lang (org-element-property :language inline-src-block)))
+    (pcase (plist-get info :latex-listings)
+      ('nil (org-latex--text-markup code 'code info))
+      ('minted (org-latex-inline-src-block--minted info code lang))
+      (_ (org-latex-inline-src-block--listings info code lang)))))
+
+(defun org-latex-inline-src-block--minted (info code lang)
+  (let ((mint-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-minted-langs)))
+                       (downcase org-lang)))
+        (options (org-latex--make-option-string
+                  (plist-get info :latex-minted-options))))
+    (format "\\mintinline%s{%s}{%s}"
+            (if (string= options "") "" (format "[%s]" options))
+            mint-lang
+            code)))
+
+(defun org-latex-inline-src-block--listings (info code lang)
+  (let* ((lst-lang (or (cadr (assq (intern lang)
+                                   (plist-get info :latex-listings-langs)))
+                       org-lang))
+         (separator (org-latex--find-verb-separator code))
+         (options (org-latex--make-option-string
+                   (append (plist-get info :latex-listings-options)
+                           `(("language" ,lst-lang))))))
+    (concat (format "\\lstinline[%s]" options)
+            separator code separator)))
 
 ;;;; Inlinetask
 
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-ox-latex-More-versitile-option-construction.patch --]
[-- Type: text/x-patch, Size: 4116 bytes --]

From b322e67cc8b88826be26ee8ae155467aa764e743 Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Wed, 4 May 2022 23:31:59 +0800
Subject: [PATCH 3/4] ox-latex: More versitile option construction

* lisp/ox-latex.el (org-latex--make-option-string): Support a custom
option seperator string.

(org-latex--make-option-string, org-latex-minted-options,
org-latex-listings-options): The first line of the docstrings for
`org-latex-minted-options` and `org-latex-listings-options` describe the
variables as "association lists", yet `org-latex--make-option-string`
does not handle association lists and an example of two-value lists is
provided.  To make the behaviour match the docstring,
`org-latex--make-option-string` is modified to work with either a list
two-value lists or an association list, and the examples in
`org-latex-minted-options` and `org-latex-listings-options` updated
accordingly.
---
 lisp/ox-latex.el | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index ed66a51c0..6a29efcba 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1006,12 +1006,16 @@ (defcustom org-latex-listings-options nil
 
 These options are supplied as a comma-separated list to the
 \\lstset command.  Each element of the association list should be
-a list containing two strings: the name of the option, and the
-value.  For example,
+a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-listings-options
     \\='((\"basicstyle\" \"\\\\small\")
       (\"keywordstyle\" \"\\\\color{black}\\\\bfseries\\\\underbar\")))
+  ; or
+  (setq org-latex-listings-options
+    \\='((\"basicstyle\" . \"\\\\small\")
+      (\"keywordstyle\" . \"\\\\color{black}\\\\bfseries\\\\underbar\")))
 
 will typeset the code in a small size font with underlined, bold
 black keywords.
@@ -1059,11 +1063,14 @@ (defcustom org-latex-minted-options nil
 
 These options are supplied within square brackets in
 \\begin{minted} environments.  Each element of the alist should
-be a list containing two strings: the name of the option, and the
-value.  For example,
+be a list or cons cell containing two strings: the name of the
+option, and the value.  For example,
 
   (setq org-latex-minted-options
     \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-minted-options
+    \\='((\"bgcolor\" . \"bg\") (\"frame\" . \"lines\")))
 
 will result in source blocks being exported with
 
@@ -1506,21 +1513,24 @@ (defun org-latex--find-verb-separator (s)
 	     when (not (string-match (regexp-quote (char-to-string c)) s))
 	     return (char-to-string c))))
 
-(defun org-latex--make-option-string (options)
+(defun org-latex--make-option-string (options &optional seperator)
   "Return a comma separated string of keywords and values.
 OPTIONS is an alist where the key is the options keyword as
 a string, and the value a list containing the keyword value, or
 nil."
   (mapconcat (lambda (pair)
-	       (pcase-let ((`(,keyword ,value) pair))
-		 (concat keyword
-			 (and (> (length value) 0)
-			      (concat "="
-                                      (if (string-match-p (rx (any "[]")) value)
-                                          (format "{%s}" value)
-                                        value))))))
-	     options
-	     ","))
+               (let ((keyword (car pair))
+                     (value (pcase (cdr pair)
+                              ((pred stringp) (cdr pair))
+                              ((pred consp) (cadr pair)))))
+                 (concat keyword
+                         (when value
+                           (concat "="
+                                   (if (string-match-p (rx (any "[]")) value)
+                                       (format "{%s}" value)
+                                     value))))))
+             options
+             (or seperator ",")))
 
 (defun org-latex--wrap-label (element output info)
   "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-- 
2.35.3


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-ox-latex-Introduce-engraved-code-highlighting.patch --]
[-- Type: text/x-patch, Size: 15169 bytes --]

From e0310e21e260a930e06d704ec8893ab1e75518aa Mon Sep 17 00:00:00 2001
From: TEC <tec@tecosaur.com>
Date: Sun, 21 Nov 2021 20:04:12 +0800
Subject: [PATCH 4/4] ox-latex: Introduce "engraved" code highlighting

* lisp/ox-latex.el (org-latex-src-block, org-latex-src-block--engraved,
org-latex-inline-src-block, org-latex-inline-src-block--engraved,
org-latex-template, org-latex-listings): Make use of the engraved-faces
package (available on ELPA) to provide an alternative LaTeX code
highlighting backend which functions similarly to htmlize.el for HTML
exports.

(org-latex-engraved-preamble, org-latex-engraved-options): Introduce
variables to construct the preamble for engraved code blocks.

* lisp/ox-beamer.el (org-beamer-template): Modify to add engrave-faces
preamble when applicable.
---
 lisp/ox-beamer.el |   9 ++
 lisp/ox-latex.el  | 235 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 241 insertions(+), 3 deletions(-)

diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 6be73c91e..ca1aeafe4 100644
--- a/lisp/ox-beamer.el
+++ b/lisp/ox-beamer.el
@@ -857,6 +857,15 @@ (defun org-beamer-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
 	    (format-spec template (org-latex--format-spec info))))
+     ;; engrave-faces-latex preamble
+     (let ((engraved-p (eq org-latex-listings 'engraved))
+           (src-p (org-element-map (plist-get info :parse-tree)
+                      '(src-block inline-src-block) #'identity))
+           (fixedw-p
+            (org-element-map (plist-get info :parse-tree)
+                '(example-block fixed-width) #'identity)))
+       (when (or src-p fixedw-p)
+         (org-latex-generate-engraved-preamble info src-p)))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 6a29efcba..4cc82f6e7 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -37,6 +37,8 @@ (defvar org-latex-default-packages-alist)
 (defvar org-latex-packages-alist)
 (defvar orgtbl-exp-regexp)
 
+(declare-function engrave-faces-latex-gen-preamble "ext:engrave-faces-latex")
+(declare-function engrave-faces-latex-buffer "ext:engrave-faces-latex")
 
 \f
 ;;; Define Back-End
@@ -125,6 +127,8 @@ (org-export-define-backend 'latex
     (:latex-default-quote-environment nil nil org-latex-default-quote-environment)
     (:latex-default-table-mode nil nil org-latex-default-table-mode)
     (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format)
+    (:latex-engraved-options nil nil org-latex-engraved-options)
+    (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
     (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format)
     (:latex-footnote-separator nil nil org-latex-footnote-separator)
     (:latex-format-drawer-function nil nil org-latex-format-drawer-function)
@@ -946,7 +950,24 @@ (defcustom org-latex-listings nil
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\"))
   (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\"))
 
-Alternatively,
+There are two fancier options for fontification.
+
+The first fancy alternative,
+
+  (setq org-latex-listings \\='engraved)
+
+causes source code to be run through
+`engrave-faces-latex-buffer', which generates colorings using
+Emacs' font-lock information.  This requires the engrave-faces
+package (availible from ELPA), and the fvextra LaTeX package be
+installed.
+
+The styling of the engraved result can customised with
+`org-latex-engraved-preamble' and `org-latex-engraved-options'.
+The default preamble also uses the tcolorbox LaTeX package in
+addition to fvextra.
+
+The second fancy alternative,
 
   (setq org-latex-listings \\='minted)
 
@@ -971,8 +992,9 @@ (defcustom org-latex-listings nil
   :type '(choice
 	  (const :tag "Use listings" t)
 	  (const :tag "Use minted" minted)
+	  (const :tag "Use engrave-faces-latex" engraved)
 	  (const :tag "Export verbatim" nil))
-  :safe (lambda (s) (memq s '(t nil minted))))
+  :safe (lambda (s) (memq s '(t nil minted engraved))))
 
 (defcustom org-latex-listings-langs
   '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp")
@@ -1142,6 +1164,109 @@ (defcustom org-latex-custom-lang-environments nil
   :version "26.1"
   :package-version '(Org . "9.0"))
 
+(defcustom org-latex-engraved-preamble
+  "\\usepackage{fvextra}
+
+[FVEXTRA-SETUP]
+
+\\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
+
+\\providecolor{codebackground}{HTML}{f7f7f7}
+\\providecolor{codeborder}{HTML}{f0f0f0}
+\\providecolor{EFD}{HTML}{28292e}
+
+% TODO have code boxes keep line vertical alignment
+\\usepackage[breakable,xparse]{tcolorbox}
+\\DeclareTColorBox[]{Code}{o}%
+{colback=codebackground, colframe=codeborder,
+  fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
+  colupper=EFD,
+  IfNoValueTF={#1}%
+  {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
+    boxrule=0.5pt, left=2pt}%
+  {boxsep=2.5pt, arc=0pt, outer arc=0pt,
+    boxrule=0pt, leftrule=1.5pt, left=0.5pt},
+  right=2pt, top=1pt, bottom=0.5pt,
+  breakable}"
+  "Preamble content injected when using engrave-faces-latex for source blocks.
+This is relevant when `org-latex-listings' is set to `engraved'.
+
+There is quite a lot of flexibility in what this preamble can be, as long as it:
+- Loads the fvextra package.
+- Defines a \"Code\" environment (note the capital C), which can be
+  later used to wrap \"Verbatim\" environments (provided by fvextra).
+
+A macro-like placeholder is used to set fvextra's defaults according to
+`org-latex-engraved-options':
+
+  [FVEXTRA-SETUP]"
+  :group 'org-export-latex
+  :type 'string
+  :package-version '(Org . "9.6"))
+
+(defcustom org-latex-engraved-options
+  '(("commandchars" . "\\\\\\{\\}")
+    ("highlightcolor" . "white!95!black!80!blue")
+    ("breaklines" . "true")
+    ("breaksymbol" . "\\color{white!60!black}\\tiny\\ensuremath{\\hookrightarrow}"))
+  "Association list of options for the latex fvextra package when engraving code.
+
+These options are set using \\fvset{...} in the preamble of the
+LaTeX export.  Each element of the alist should be a list or cons
+cell containing two strings: the name of the option, and the
+value.  For example,
+
+  (setq org-latex-engraved-options
+    \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
+  ; or
+  (setq org-latex-engraved-options
+    \\='((\"bgcolor\" . \"bg\") (\"frame\" . \"lines\")))
+
+will result in the following LaTeX in the preamble
+
+\\fvset{%
+  bgcolor=bg,
+  frame=lines}
+
+This will affect all fvextra environments.  Note that the same
+options will be applied to all blocks.  If you need
+block-specific options, you may use the following syntax:
+
+  #+ATTR_LATEX: :options key1=value1,key2=value2
+  #+BEGIN_SRC <LANG>
+  ...
+  #+END_SRC")
+
+(defun org-latex-generate-engraved-preamble (info syntax-colours-p)
+  (let* ((engraved-options
+          (plist-get info :latex-engraved-options))
+         (engraved-preamble-template
+          (plist-get info :latex-engraved-preamble))
+         (engraved-preamble
+          (if (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?"
+                            org-latex-engraved-preamble)
+              (replace-match
+               (concat
+                "\\fvset{%\n  "
+                (org-latex--make-option-string engraved-options ",\n  ")
+                "}\n")
+               t t
+               engraved-preamble-template)
+            engraved-preamble-template)))
+    (if syntax-colours-p
+        (concat
+         "\n% Setup for code blocks [1/2]\n\n"
+         engraved-preamble
+         "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n"
+         (if (require 'engrave-faces-latex nil t)
+             (engrave-faces-latex-gen-preamble)
+           (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
+           "% WARNING syntax highlighting unavailible as engrave-faces-latex was missing.\n")
+         "\n")
+      (concat
+       "\n% Setup for code blocks\n\n"
+       engraved-preamble
+       "\n"))))
 
 ;;;; Compilation
 
@@ -1756,6 +1881,15 @@ (defun org-latex-template (contents info)
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
             (format-spec template spec)))
+     ;; engrave-faces-latex preamble
+     (let ((engraved-p (eq org-latex-listings 'engraved))
+           (src-p (org-element-map (plist-get info :parse-tree)
+                      '(src-block inline-src-block) #'identity))
+           (fixedw-p
+            (org-element-map (plist-get info :parse-tree)
+                '(example-block fixed-width) #'identity)))
+       (when (or src-p fixedw-p)
+         (org-latex-generate-engraved-preamble info src-p)))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
@@ -2142,12 +2276,13 @@ (defun org-latex-inline-src-block (inline-src-block _contents info)
     (pcase (plist-get info :latex-listings)
       ('nil (org-latex--text-markup code 'code info))
       ('minted (org-latex-inline-src-block--minted info code lang))
+      ('engraved (org-latex-inline-src-block--engraved info code lang))
       (_ (org-latex-inline-src-block--listings info code lang)))))
 
 (defun org-latex-inline-src-block--minted (info code lang)
   (let ((mint-lang (or (cadr (assq (intern lang)
                                    (plist-get info :latex-minted-langs)))
-                       (downcase org-lang)))
+                       (downcase lang)))
         (options (org-latex--make-option-string
                   (plist-get info :latex-minted-options))))
     (format "\\mintinline%s{%s}{%s}"
@@ -2155,6 +2290,23 @@ (defun org-latex-inline-src-block--minted (info code lang)
             mint-lang
             code)))
 
+(defun org-latex-inline-src-block--engraved (info code lang)
+  (if (require 'engrave-faces-latex nil t)
+      (let (engraved-buffer engraved-code)
+        (setq engraved-buffer
+              (with-temp-buffer
+                (insert code)
+                (funcall (org-src-get-lang-mode lang))
+                (engrave-faces-latex-buffer)))
+        (setq engraved-code
+              (with-current-buffer engraved-buffer
+                (buffer-string)))
+        (kill-buffer engraved-buffer)
+        (format "\\Verb{%s}"
+                engraved-code))
+    (message "Cannot engrave inline src block, `engrave-faces-latex' is unavailible.")
+    (insert (org-latex--text-markup code 'code info))))
+
 (defun org-latex-inline-src-block--listings (info code lang)
   (let* ((lst-lang (or (cadr (assq (intern lang)
                                    (plist-get info :latex-listings-langs)))
@@ -3013,6 +3165,9 @@ (defun org-latex-src-block (src-block _contents info)
                                      num-start retain-labels attributes float custom-env))
        ((eq listings 'minted)
         (org-latex-src-block--minted src-block info lang caption caption-above-p label
+                                     num-start retain-labels attributes float))
+       ((eq listings 'engraved)
+        (org-latex-src-block--engraved src-block info lang caption caption-above-p label
                                        num-start retain-labels attributes float))
        (t
         (org-latex-src-block--listings src-block info lang caption caption-above-p label
@@ -3129,6 +3284,80 @@ (defun org-latex-src-block--minted
     ;; Return value.
     (format float-env body)))
 
+(defun org-latex-src-block--engraved
+    (src-block info lang caption caption-above-p _label
+               num-start retain-labels attributes float)
+  "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
+LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
+and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
+  (if (require 'engrave-faces-latex nil t)
+  (let* ((caption-str (org-latex--caption/label-string src-block info))
+         (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
+                        (plist-get info :latex-default-figure-position)))
+         (float-env
+          (cond
+           ((string= "multicolumn" float)
+            (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           (caption
+            (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
+                    placement
+                    (if caption-above-p caption-str "")
+                    (if caption-above-p "" caption-str)))
+           ((string= "t" float)
+            (concat (format "\\begin{listing}[%s]\n"
+                            placement)
+                    "%s\n\\end{listing}"))
+           (t "%s")))
+         (options (plist-get info :latex-engraved-options))
+         (content-buffer
+          (with-temp-buffer
+            (insert
+             (let* ((code-info (org-export-unravel-code src-block))
+                    (max-width
+                     (apply 'max
+                            (mapcar 'length
+                                    (org-split-string (car code-info)
+                                                      "\n")))))
+               (org-export-format-code
+                (car code-info)
+                (lambda (loc _num ref)
+                  (concat
+                   loc
+                   (when ref
+                     ;; Ensure references are flushed to the right,
+                     ;; separated with 6 spaces from the widest line
+                     ;; of code.
+                     (concat (make-string (+ (- max-width (length loc)) 6)
+                                          ?\s)
+                             (format "(%s)" ref)))))
+                nil (and retain-labels (cdr code-info)))))
+            (funcall (org-src-get-lang-mode lang))
+            (engrave-faces-latex-buffer)))
+         (content
+          (with-current-buffer content-buffer
+            (buffer-string)))
+         (body
+          (format
+           "\\begin{Code}\n\\begin{Verbatim}[%s]\n%s\\end{Verbatim}\n\\end{Code}"
+           ;; Options.
+           (concat
+            (org-latex--make-option-string
+             (append
+              (when (and num-start (not (assoc "linenos" options)))
+                `(("linenos")
+                  ("firstnumber" ,(number-to-string (1+ num-start)))))
+              (let ((local-options (plist-get attributes :options)))
+                (and local-options (list local-options))))))
+           content)))
+    (kill-buffer content-buffer)
+    ;; Return value.
+    (format float-env body))
+  (message "Cannot engrave src block, `engrave-faces-latex' is unavailible.")
+  (insert (org-latex--text-markup code 'code info))))
+
 (defun org-latex-src-block--listings
     (src-block info lang caption caption-above-p label
                num-start retain-labels attributes float)
-- 
2.35.3


^ permalink raw reply related	[relevance 5%]

* Bug: File variable no longer on first line when running org-id-get-create [9.4.4 (release_9.4.4 @ /usr/share/emacs/27.2/lisp/org/)]
@ 2021-08-21 21:58  1% Peter Prevos
  0 siblings, 0 replies; 200+ results
From: Peter Prevos @ 2021-08-21 21:58 UTC (permalink / raw)
  To: emacs-orgmode


Hi, I use file variables on the first line of some Org mode files 
to indicate the local Flyspell dictionary, e.g.:

-*- mode: org; ispell-local-dictionary: "nederlands" -*-

This line sets the dictionary to Dutch for this file only.

This is useful functionality that allows me to indicate the 
language of files other than my default language.

It works great, except when I need to add an ID for use in 
Org-Roam using the org-id-get-create function.

The new drawer is placed on the first line of the buffer, so the 
local variable declaration moves down and is as such no longer 
recognised as it is expected on line 1. (File variable 
documentation: 
https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html)

There is an ugly workaround by placing file variables at the end 
of the file, as documented in the linked page.

Regards

P:)

-- 
Dr Peter Prevos
---------------
peterprevos.com



Emacs  : GNU Emacs 27.2 (build 1, x86_64-pc-linux-gnu, GTK+ 
Version 3.24.27, cairo version 1.17.4)
 of 2021-03-27
Package: Org mode version 9.4.4 (release_9.4.4 @ 
/usr/share/emacs/27.2/lisp/org/)

current state:
==============
(setq
 org-ref-notes-directory "/home/peter/Documents/org-roam/"
) org-roam-db-location 
"/home/peter/Documents/org-roam/data/org-roam.db"
 org-src-mode-hook '(org-src-babel-configure-edit-buffer 
 org-src-mode-configure-edit-buffer
		     doom-modeline-set-org-src-modeline)
 org-capture-prepare-finalize-hook 
 '(org-roam-capture--install-finalize-h)
 org-link-shell-confirm-function nil
 org-num-format-function 'org-num-default-format
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-clock-out-hook '(org-clock-remove-empty-clock-drawer)
 org-roam-db-node-include-function #[0 "\300\207" [t] 1]
 org-refile-targets '((gtd-file :maxlevel . 2))
 org-html-format-inlinetask-function 
 'org-html-format-inlinetask-default-function
 org-export-with-todo-keywords nil
 org-ref-create-notes-hook '((lambda nil (org-narrow-to-subtree)
			      (insert
			       (format "cite:%s\n" (org-entry-get 
			       (point) "CUSTOM_ID")))
			      )
			     )
 org-odt-format-headline-function 
 'org-odt-format-headline-default-function
 org-latex-pdf-process '("pdflatex -interaction nonstopmode 
 -output-directory %o %f"
			 "bibtex %b"
			 "pdflatex -shell-escape -interaction 
			 nonstopmode -output-directory %o %f" 
			 "pdflatex -shell-escape -interaction 
			 nonstopmode -output-directory %o %f")
 org-agenda-files '("~/Documents/org-roam/gtd.org")
 org-ascii-format-inlinetask-function 
 'org-ascii-format-inlinetask-default
 org-odt-preferred-output-format "doc"
 org-mode-hook '(org-ref-org-menu org-appear-mode org-fragtog-mode
		 #[0 "\301\211\207" [imenu-create-index-function 
                  org-imenu-get-tree] 2]
		 writegood-mode (lambda nil (org-superstar-mode 
		 1))
		 #[0 "\300\301\302\303\304$\207"
		   [add-hook change-major-mode-hook org-show-all 
		   append local] 5]
		 #[0 "\300\301\302\303\304$\207"
		   [add-hook change-major-mode-hook 
		   org-babel-show-result-all append local] 5]
		 org-babel-result-hide-spec 
		 org-babel-hide-all-hashes
		 org-ref-setup-label-finders)
 org-ref-insert-cite-function 'org-ref-helm-insert-cite-link
 org-export-with-smart-quotes t
 org-odt-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME 
 CONTENTS)"]
 org-archive-hook '(org-attach-archive-delete-maybe)
 org-startup-indented t
 org-reverse-note-order t
 org-ref-clean-bibtex-key-function '(lambda (key) 
 (replace-regexp-in-string ":" "" key))
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-hide-block-startup t
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-bibtex-headline-format-function #[257 "\300\236A\207" 
 [:title] 3 "\n\n(fn ENTRY)"]
 org-ref-cite-keymap '(keymap
		       (tab lambda nil (interactive) (funcall 
		       org-ref-insert-cite-function))
		       (S-up . org-ref-sort-citation-link)
		       (S-right lambda nil (interactive) 
		       (org-ref-swap-citation-link 1))
		       (S-left lambda nil (interactive) 
		       (org-ref-swap-citation-link -1))
		       (C-right . right-word) (C-left . left-word)
		       (16777337 lambda nil
			"Paste key at point. Assumes the first 
			thing in the killring is a key."
			(interactive) (org-ref-insert-key-at-point 
			(car kill-ring)))
		       (16777303 lambda nil "Copy all the keys at 
		       point." (interactive)
			(kill-new (org-element-property :path 
			(org-element-context))))
		       (16777335 lambda nil (interactive)
			(kill-new (car 
			(org-ref-get-bibtex-key-and-file))))
		       (16777318 lambda nil (interactive)
			(save-excursion 
			(org-ref-open-citation-at-point)
			 (kill-new 
			 (org-ref-format-bibtex-entry-at-point)))
			)
		       (16777319 
		       . org-ref-google-scholar-at-point)
		       (16777317 lambda nil "Email entry at point" 
		       (interactive)
			(org-ref-open-citation-at-point) 
			(org-ref-email-bibtex-entry))
		       (16777315 . org-ref-wos-citing-at-point)
		       (16777330 . org-ref-wos-related-at-point)
		       (16777326 . org-ref-open-notes-at-point)
		       (16777328 lambda nil (interactive) (funcall 
		       org-ref-open-pdf-function))
		       (16777333 . org-ref-open-url-at-point)
		       (16777314 . org-ref-open-citation-at-point)
		       (16777327 . org-ref-cite-hydra/body) 
		       (follow-link . mouse-face)
		       (mouse-3 . org-find-file-at-mouse) (mouse-2 
		       . org-open-at-mouse))
 org-latex-format-drawer-function #[514 "\207" [] 3 "\n\n(fn _ 
 CONTENTS)"]
 org-babel-pre-tangle-hook '(save-buffer)
 org-file-apps '((auto-mode . emacs) (directory . emacs) 
 ("\\.mp4\\'" . "vlc \"%s\""))
 org-tab-first-hook '(org-babel-hide-result-toggle-maybe 
 org-babel-header-arg-expand)
 org-export-with-drawers nil
 org-babel-load-languages '((emacs-lisp . t) (R . t) (python . t) 
 (shell . t) (latex . t))
 org-ref-clean-bibtex-entry-hook 
 '(org-ref-bibtex-format-url-if-doi orcb-key-comma
				   org-ref-replace-nonascii orcb-& 
				   orcb-%
				   org-ref-title-case-article 
				   orcb-clean-year orcb-key
				   orcb-clean-doi orcb-clean-pages 
				   orcb-check-journal
				   org-ref-sort-bibtex-entry 
				   orcb-fix-spacing)
 org-roam-capture-preface-hook 
 '(org-roam-dailies--override-capture-time-h)
 org-hide-emphasis-markers t
 org-ref-insert-label-function 'org-ref-helm-insert-label-link
 org-roam-capture-templates '(("d" "default" plain "%?" :if-new
			       (file+head "${slug}.org"
				"#+title: ${title}\n#+date: 
				%u\n#+lastmod: \n#+startup: 
				inlineimages latexpreview 
				entitiespretty\n*topics*: \n\n")
			       :unnarrowed t :immediate-finish t)
			      ("r" "bibliography reference" plain 
			      "\n$%?" :if-new
			       (file+head "${citekey}.org"
				"#+title: ${title}\n#+date: 
				%u\n#+lastmod: \n#+startup: 
				inlineimages latexpreview 
				entitiespretty\n*topics*: \n\n")
			       :unnarrowed t :immediate-finish t)
			      )
 org-ref-open-pdf-function 'org-ref-open-pdf-at-point
 org-ascii-format-drawer-function #[771 "\207" [] 4 "\n\n(fn NAME 
 CONTENTS WIDTH)"]
 org-ellipsis " ↲"
 org-ref-open-notes-function '(lambda nil (org-show-entry) 
 (outline-show-branches)
			       (outline-show-children) (org-cycle 
			       '(64))
			       (recenter-top-bottom 0))
 org-agenda-loop-over-headlines-in-active-region nil
 org-roam-find-file-hook '(org-roam-buffer--setup-redisplay-h
			   org-roam--register-completion-functions-h
			   org-roam--replace-roam-links-on-save-h
			   org-roam-open-id-with-org-roam-db-h
			   org-roam-db-autosync--setup-update-on-save-h)
 org-catch-invisible-edits 'error
 org-occur-hook '(org-first-headline-recenter)
 org-log-into-drawer t
 org-ref-bibtex-assoc-pdf-with-entry-move-function 'rename-file
 org-ref-insert-link-function 'org-ref-helm-insert-cite-link
 org-ref-insert-ref-function 'org-ref-helm-insert-ref-link
 org-agenda-include-diary t
 org-structure-template-alist '(("a" . "export ascii\n") ("c" 
 . "center\n")
				("C" . "comment\n") ("e" 
				. "example\n") ("E" . "export")
				("h" . "export html\n") ("l" 
				. "export latex\n")
				("q" . "quote\n") ("s" . "src\n") 
				("sl" . "src emacs-lisp\n")
				("sr" . "src R\n") ("sf" . "src 
				fountain\n")
				("sp" . "src python\n") ("v" 
				. "verse\n"))
 org-cycle-hook '(org-cycle-hide-archived-subtrees 
 org-cycle-hide-drawers
		  org-cycle-show-empty-lines 
		  org-optimize-window-after-visibility-change)
 org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAITING(w@/!)" 
 "PROJECT(p)" "GOAL(g)" "|"
		      "DONE(d/!)" "CANCELLED(c@/!)")
		     )
 org-speed-command-hook '(org-speed-command-activate 
 org-babel-speed-command-activate)
 org-msg-startup "hidestars indent inlineimages"
 org-roam-node-annotation-function 'org-roam-node-read--annotation
 org-ref-default-bibliography 
 '("/home/peter/Documents/org-roam/bibliography/horizon-of-reason.bib" 
 "/home/peter/Documents/org-roam/bibliography/lucid-manager.bib" 
 "/home/peter/Documents/org-roam/bibliography/magic-compass.bib" 
 "/home/peter/Documents/org-roam/bibliography/magic-tricks.bib" 
 "/home/peter/Documents/org-roam/bibliography/science-of-magic.bib" 
 "/home/peter/Documents/org-roam/bibliography/zotero.bib")
 org-log-repeat nil
 org-odt-format-inlinetask-function 
 'org-odt-format-inlinetask-default-function
 org-ref-completion-library 'org-ref-helm-cite
 org-roam-ref-annotation-function 'org-roam-ref-read--annotation
 org-ref-cite-types '("citeA" "cite" "nocite" "citet" "citet*" 
 "citep" "citep*" "citealt"
		      "citealt*" "citealp" "citealp*" "citenum" 
		      "citetext" "citeauthor"
		      "citeauthor*" "citeyear" "citeyear*" 
		      "citeyearpar" "Citet" "Citep"
		      "Citealt" "Citealp" "Citeauthor" "Cite" 
		      "parencite" "Parencite"
		      "footcite" "footcitetext" "textcite" 
		      "Textcite" "smartcite" "Smartcite"
		      "cite*" "parencite*" "supercite" "autocite" 
		      "Autocite" "autocite*"
		      "Autocite*" "Citeauthor*" "citetitle" 
		      "citetitle*" "citedate"
		      "citedate*" "citeurl" "fullcite" 
		      "footfullcite" "notecite" "Notecite"
		      "pnotecite" "Pnotecite" "fnotecite" "cites" 
		      "Cites" "parencites"
		      "Parencites" "footcites" "footcitetexts" 
		      "smartcites" "Smartcites"
		      "textcites" "Textcites" "supercites" 
		      "autocites" "Autocites" "bibentry")
 org-babel-tangle-lang-exts '(("latex" . "tex") ("python" . "py") 
 ("emacs-lisp" . "el")
			      ("elisp" . "el"))
 org-ref-pdf-to-bibtex-function 'copy-file
 org-export-before-parsing-hook '(org-attach-expand-links 
 org-ref-acronyms-before-parsing
				  org-ref-glossary-before-parsing)
 org-stuck-projects '("/PROJECT" ("NEXT" "WAITING") nil)
 org-link-parameters '(("attachment" :follow org-attach-follow 
 :complete
			org-attach-complete-link)
		       ("deft" :follow deft--org-follow-link 
		       :store org-deft-store-link
			:complete deft--org-complete)
		       ("mu4e" :follow mu4e-org-open :store 
		       mu4e-org-store-link)
		       ("roam" :follow org-roam-link-follow-link) 
		       ("id" :follow org-id-open)
		       ("eww" :follow org-eww-open :store 
		       org-eww-store-link)
		       ("rmail" :follow org-rmail-open :store 
		       org-rmail-store-link)
		       ("mhe" :follow org-mhe-open :store 
		       org-mhe-store-link)
		       ("irc" :follow org-irc-visit :store 
		       org-irc-store-link :export
			org-irc-export)
		       ("info" :follow org-info-open :export 
		       org-info-export :store
			org-info-store-link)
		       ("gnus" :follow org-gnus-open :store 
		       org-gnus-store-link)
		       ("docview" :follow org-docview-open :export 
		       org-docview-export :store
			org-docview-store-link)
		       ("bbdb" :follow org-bbdb-open :export 
		       org-bbdb-export :complete
			org-bbdb-complete-link :store 
			org-bbdb-store-link)
		       ("w3m" :store org-w3m-store-link)
		       ("hugo" :complete
			(lambda nil
			 (concat "{{% ref " (file-relative-name 
			 (read-file-name "File: "))
			  " %}}")
			 )
			)
		       ("citeA" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citeA :complete 
			org-citeA-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("printindex" :follow org-ref-index :export
			#[(path desc format) "\b\301=\205 
                         \300\302!\207"
			  [format latex "\\printindex"] 2]
			)
		       ("index" :follow #[(path) "\301\b!\207" 
		       [path occur] 2] :export
			#[(path desc format) 
                         "\b\302=\205\n\300\303	\"\207"
			  [format path latex "\\index{%s}"] 3]
			)
		       ("bibentry" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-bibentry :complete 
			org-bibentry-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Autocites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Autocites :complete 
			org-Autocites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("autocites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-autocites :complete 
			org-autocites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("supercites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-supercites :complete 
			org-supercites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Textcites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Textcites :complete 
			org-Textcites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("textcites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-textcites :complete 
			org-textcites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Smartcites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Smartcites :complete 
			org-Smartcites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("smartcites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-smartcites :complete 
			org-smartcites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footcitetexts" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-footcitetexts :complete
			org-footcitetexts-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footcites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-footcites :complete 
			org-footcites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Parencites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Parencites :complete 
			org-Parencites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("parencites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-parencites :complete 
			org-parencites-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Cites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Cites :complete 
			org-Cites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("cites" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-cites :complete 
			org-cites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("fnotecite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-fnotecite :complete 
			org-fnotecite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Pnotecite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Pnotecite :complete 
			org-Pnotecite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("pnotecite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-pnotecite :complete 
			org-pnotecite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Notecite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Notecite :complete 
			org-Notecite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("notecite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-notecite :complete 
			org-notecite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footfullcite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-footfullcite :complete 
			org-footfullcite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("fullcite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-fullcite :complete 
			org-fullcite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeurl" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citeurl :complete 
			org-citeurl-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citedate*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citedate* :complete 
			org-citedate*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citedate" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citedate :complete 
			org-citedate-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citetitle*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citetitle* :complete 
			org-citetitle*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citetitle" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citetitle :complete 
			org-citetitle-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citeauthor*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Citeauthor* :complete 
			org-Citeauthor*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Autocite*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Autocite* :complete 
			org-Autocite*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("autocite*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-autocite* :complete 
			org-autocite*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Autocite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Autocite :complete 
			org-Autocite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("autocite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-autocite :complete 
			org-autocite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("supercite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-supercite :complete 
			org-supercite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("parencite*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-parencite* :complete 
			org-parencite*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("cite*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-cite* :complete 
			org-cite*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Smartcite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Smartcite :complete 
			org-Smartcite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("smartcite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-smartcite :complete 
			org-smartcite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Textcite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Textcite :complete 
			org-Textcite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("textcite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-textcite :complete 
			org-textcite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footcitetext" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-footcitetext :complete 
			org-footcitetext-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footcite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-footcite :complete 
			org-footcite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Parencite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Parencite :complete 
			org-Parencite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("parencite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-parencite :complete 
			org-parencite-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Cite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Cite :complete 
			org-Cite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citeauthor" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Citeauthor :complete 
			org-Citeauthor-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citealp" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Citealp :complete 
			org-Citealp-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citealt" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Citealt :complete 
			org-Citealt-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citep" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Citep :complete 
			org-Citep-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citet" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-Citet :complete 
			org-Citet-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeyearpar" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citeyearpar :complete 
			org-citeyearpar-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeyear*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citeyear* :complete 
			org-citeyear*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeyear" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citeyear :complete 
			org-citeyear-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeauthor*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citeauthor* :complete 
			org-citeauthor*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeauthor" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citeauthor :complete 
			org-citeauthor-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citetext" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citetext :complete 
			org-citetext-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citenum" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citenum :complete 
			org-citenum-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citealp*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citealp* :complete 
			org-citealp*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citealp" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citealp :complete 
			org-citealp-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citealt*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citealt* :complete 
			org-citealt*-complete-link
			:help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citealt" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citealt :complete 
			org-citealt-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citep*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citep* :complete 
			org-citep*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citep" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citep :complete 
			org-citep-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citet*" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citet* :complete 
			org-citet*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citet" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-citet :complete 
			org-citet-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("nocite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-nocite :complete 
			org-nocite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			)
		       ("cite" :follow
			(lambda (_) (funcall 
			org-ref-cite-onclick-function nil)) 
			:export
			org-ref-format-cite :complete 
			org-cite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s (org-ref-format-entry 
			    (org-ref-get-bibtex-key-under-cursor))))
			    (with-temp-buffer (insert s) 
			    (fill-paragraph) (buffer-string)))
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display 
			full :keymap
			(keymap
			 (tab lambda nil (interactive) (funcall 
			 org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive) 
			 (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive) 
			 (org-ref-swap-citation-link -1))
			 (C-right . right-word) (C-left 
			 . left-word)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first 
			  thing in the killring is a key."
			  (interactive) 
			  (org-ref-insert-key-at-point (car 
			  kill-ring)))
			 (16777303 lambda nil "Copy all the keys 
			 at point." (interactive)
			  (kill-new (org-element-property :path 
			  (org-element-context))))
			 (16777335 lambda nil (interactive)
			  (kill-new (car 
			  (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion 
			  (org-ref-open-citation-at-point)
			   (kill-new 
			   (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 
			 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at 
			 point" (interactive)
			  (org-ref-open-citation-at-point) 
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 lambda nil (interactive)
			  (funcall org-ref-open-pdf-function))
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 
			 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body) 
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse) 
			 (mouse-2 . org-open-at-mouse))
			:store org-ref-bibtex-store-link)
		       ("Cref" :follow org-ref-ref-follow :export 
		       org-ref-Cref-export
			:complete
			#[(&optional arg) "\301\b\302\"\207"
			  [arg org-ref-complete-link "Cref"] 3]
			:face org-ref-ref-face-fn :help-echo 
			org-ref-ref-help-echo)
		       ("cref" :follow org-ref-ref-follow :export 
		       org-ref-cref-export
			:complete
			#[(&optional arg) "\301\b\302\"\207"
			  [arg org-ref-complete-link "cref"] 3]
			:face org-ref-ref-face-fn :help-echo 
			org-ref-ref-help-echo)
		       ("autoref" :follow org-ref-ref-follow 
		       :export org-ref-autoref-export
			:complete
			#[(&optional arg) "\301\b\302\"\207"
			  [arg org-ref-complete-link "autoref"] 3]
			:face org-ref-ref-face-fn :help-echo 
			org-ref-ref-help-echo)
		       ("eqref" :follow org-ref-ref-follow :export 
		       org-ref-eqref-export
			:complete
			#[(&optional arg) "\301\b\302\"\207"
			  [arg org-ref-complete-link "eqref"] 3]
			:face org-ref-ref-face-fn :help-echo 
			org-ref-ref-help-echo)
		       ("nameref" :follow org-ref-ref-follow 
		       :export org-ref-export-nameref
			:complete
			#[(&optional arg) "\301\b\302\"\207"
			  [arg org-ref-complete-link "nameref"] 3]
			:face org-ref-ref-face-fn :help-echo 
			org-ref-ref-help-echo)
		       ("pageref" :follow org-ref-ref-follow 
		       :export
			#[(path desc format)
			  "\b\302\267\202\0\300\303 
			  \"\207\300\304	\"\207\305\207"
			  [format path #s
			   (hash-table size 2 test eq rehash-size 
			   1.5 rehash-threshold 0.8125
			    purecopy t data (html 6 latex 11))
			   "(<pageref>%s</pageref>)" 
			   "\\pageref{%s}" nil]
			  3]
			:face org-ref-ref-face-fn :complete
			#[(&optional arg) "\301\b\302\"\207"
			  [arg org-ref-complete-link "pageref"] 3]
			:help-echo org-ref-ref-help-echo)
		       ("ref" :follow org-ref-ref-follow :export 
		       org-ref-ref-export :complete
			#[(&optional arg) "\301\b\302\"\207"
			  [arg org-ref-complete-link "ref"] 3]
			:face org-ref-ref-face-fn :help-echo 
			org-ref-ref-help-echo)
		       ("label" :follow
			#[(label)
			  "\302\b!\303\304\305	\211\306U\204\0 
			  \307V\203\0\310\202\0\311#\302\b!\")\207"
			  [label count org-ref-count-labels 
			  message format "%s occurence%s" 0
			   1 "s" ""]
			  6
			  "On clicking count the number of label 
			  tags used in the buffer.\nA number 
			  greater than one means multiple 
			  labels!"]
			:export
			#[(keyword desc format)
			  "\b\302\267\202\0\300\303 
			  \"\207\300\304	\"\207\300\305 
			  \"\207\306\207"
			  [format
			   
			   keyword
			   
			   #s
			   
			   (hash-table
			    
													  
													    
														    
			    size
			    
													  
													    
														    
			    3
			    
													  
													    
														    
			    test
			    
													  
													    
														    
			    eq
			    
													  
													    
														    
			    rehash-size
			    
													  
													    
														    
			    1.5
			    
													  
													    
														    
			    rehash-threshold
			    
													  
													    
														    
			    0.8125
			    
													  
													    
														    
			    purecopy
			    
													  
													    
														    
			    t
			    
													  
													    
														    
			    data
			    
													  
													    
														    
			    (html 6 md 11 latex 16)
			    
													  
													    
														    
			    )
			   
			   "<div id=\"%s\"></div>" "<a 
			   name=\"%s\"></a>" "\\label{%s}" nil]
			  3]
			:store org-ref-label-store-link :face 
			org-ref-label-face-fn
			:help-echo
			#[(window object position)
			  "\212\bb\210\303 
			  \304\305!r\nq\210\306\216	c\210\307 
			  \210\310 -\207"
			  [position
			   
			   s
			   
			   temp-buffer
			   
			   org-ref-link-message
			   
			   generate-new-buffer
			   
			   " *temp*"
			   
			   #[nil
			     
													     
														       
																	   
																				
																					    
																					      
			     "\301\b!\205	\302\b!\207"
			     
													     
														       
																	   
																				
																					    
																					      
			     [temp-buffer buffer-name kill-buffer]
			     
			     
			     
			     
			     
			     
													     
														       
																	   
																				
																					    
																					      
			     2]
			   
			   fill-paragraph buffer-string]
			  2]
			)
		       ("list-of-tables" :follow 
		       org-ref-list-of-tables :export
			#[(keyword desc format) "\b\301=\205 
                         \300\302!\207"
			  [format latex "\\listoftables"] 2]
			)
		       ("list-of-figures" :follow 
		       org-ref-list-of-figures :export
			#[(keyword desc format) "\b\301=\205 
                         \300\302!\207"
			  [format latex "\\listoffigures"] 2]
			)
		       ("addbibresource" :follow 
		       org-ref-follow-addbibresource :export
			#[(keyword desc format)
			  "\b\302\267\202\0\300\303!\207\300\304 
			  \"\207\305\207"
			  [format keyword #s
			   (hash-table size 2 test eq rehash-size 
			   1.5 rehash-threshold 0.8125
			    purecopy t data (html 6 latex 10))
			   "" "\\addbibresource{%s}" nil]
			  3]
			)
		       ("bibliographystyle" :export
			#[(keyword desc format)
			  "\b\302=\204\f\b\303=\203\0\300\304 
			  \"\207\305\207"
			  [format keyword latex beamer 
			  "\\bibliographystyle{%s}" ""] 3]
			)
		       ("printbibliography" :follow 
		       org-ref-open-bibliography :export
			#[(keyword desc format)
			  "\b\302\267\202\0\303 \207\304 \207 
			  \207\305\207"
			  [format org-ref-printbibliography-cmd #s
			   (hash-table size 3 test eq rehash-size 
			   1.5 rehash-threshold 0.8125
			    purecopy t data (org 6 html 9 latex 
			    12))
			   org-ref-get-org-bibliography 
			   org-ref-get-html-bibliography nil]
			  2]
			)
		       ("nobibliography" :follow 
		       org-ref-open-bibliography :export
			org-ref-nobibliography-format)
		       ("bibliography" :follow 
		       org-ref-open-bibliography :export
			org-ref-bibliography-format :complete 
			org-bibliography-complete-link
			:help-echo
			#[(window object position)
			  "\212\bb\210\303 
			  \304\305!r\nq\210\306\216	c\210\307 
			  \210\310 -\207"
			  [position
			   
			   s
			   
			   temp-buffer
			   
			   org-ref-link-message
			   
			   generate-new-buffer
			   
			   " *temp*"
			   
			   #[nil
			     
													     
														       
																	   
																				
																					    
																					      
			     "\301\b!\205	\302\b!\207"
			     
													     
														       
																	   
																				
																					    
																					      
			     [temp-buffer buffer-name kill-buffer]
			     
			     
			     
			     
			     
			     
													     
														       
																	   
																				
																					    
																					      
			     2]
			   
			   fill-paragraph buffer-string]
			  2]
			:face org-ref-bibliography-face-fn)
		       ("Acp" :follow or-follow-acronym :face 
		       org-ref-acronym-face-fn
			:help-echo or-acronym-tooltip :export
			#[771 
                         "\211\301>\203\0\302\303\300A#\207\302\304\226\"\207"
			  [("Acp" . "Glspl") (latex beamer) format 
			  "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("acp" :follow or-follow-acronym :face 
		       org-ref-acronym-face-fn
			:help-echo or-acronym-tooltip :export
			#[771 
                         "\211\301>\203\0\302\303\300A#\207\302\304\226\"\207"
			  [("acp" . "glspl") (latex beamer) format 
			  "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("Ac" :follow or-follow-acronym :face 
		       org-ref-acronym-face-fn
			:help-echo or-acronym-tooltip :export
			#[771 
                         "\211\301>\203\0\302\303\300A#\207\302\304\226\"\207"
			  [("Ac" . "Gls") (latex beamer) format 
			  "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("ac" :follow or-follow-acronym :face 
		       org-ref-acronym-face-fn
			:help-echo or-acronym-tooltip :export
			#[771 
                         "\211\301>\203\0\302\303\300A#\207\302\304\226\"\207"
			  [("ac" . "gls") (latex beamer) format 
			  "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("acrfull" :follow or-follow-acronym :face 
		       org-ref-acronym-face-fn
			:help-echo or-acronym-tooltip :export
			#[771 
                         "\211\301>\203\0\302\303\300A#\207\302\304\226\"\207"
			  [("acrfull" . "acrfull") (latex beamer) 
			  format "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("acrlong" :follow or-follow-acronym :face 
		       org-ref-acronym-face-fn
			:help-echo or-acronym-tooltip :export
			#[771 
                         "\211\301>\203\0\302\303\300A#\207\302\304\226\"\207"
			  [("acrlong" . "acrlong") (latex beamer) 
			  format "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("acrshort" :follow or-follow-acronym :face 
		       org-ref-acronym-face-fn
			:help-echo or-acronym-tooltip :export
			#[771 
                         "\211\301>\203\0\302\303\300A#\207\302\304\226\"\207"
			  [("acrshort" . "acrshort") (latex 
			  beamer) format "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("glslink" :follow or-follow-glossary :face 
		       org-ref-glossary-face-fn
			:help-echo or-glossary-tooltip :export
			#[771 
                         "\211\300>\203\f\301\302\x04#\207\301\303\"\207"
			  [(latex beamer) format 
			  "\\glslink{%s}{%s}" "%s"] 7
			  "\n\n(fn PATH DESC FORMAT)"]
			)
		       ("glsdesc" :follow or-follow-glossary :face 
		       org-ref-glossary-face-fn
			:help-echo or-glossary-tooltip :export
			#[771 
                         "\211\301>\203\f\302\303\300#\207\302\304\"\207"
			  ["glsdesc" (latex beamer) format 
			  "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("glssymbol" :follow or-follow-glossary 
		       :face org-ref-glossary-face-fn
			:help-echo or-glossary-tooltip :export
			#[771 
                         "\211\301>\203\f\302\303\300#\207\302\304\"\207"
			  ["glssymbol" (latex beamer) format 
			  "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("Glspl" :follow or-follow-glossary :face 
		       org-ref-glossary-face-fn
			:help-echo or-glossary-tooltip :export
			#[771 
                         "\211\301>\203\f\302\303\300#\207\302\304\"\207"
			  ["Glspl" (latex beamer) format 
			  "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("Gls" :follow or-follow-glossary :face 
		       org-ref-glossary-face-fn
			:help-echo or-glossary-tooltip :export
			#[771 
                         "\211\301>\203\f\302\303\300#\207\302\304\"\207"
			  ["Gls" (latex beamer) format "\\%s{%s}" 
			  "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("glspl" :follow or-follow-glossary :face 
		       org-ref-glossary-face-fn
			:help-echo or-glossary-tooltip :export
			#[771 
                         "\211\301>\203\f\302\303\300#\207\302\304\"\207"
			  ["glspl" (latex beamer) format 
			  "\\%s{%s}" "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("gls" :follow or-follow-glossary :face 
		       org-ref-glossary-face-fn
			:help-echo or-glossary-tooltip :export
			#[771 
                         "\211\301>\203\f\302\303\300#\207\302\304\"\207"
			  ["gls" (latex beamer) format "\\%s{%s}" 
			  "%s"] 7
			  "\n\n(fn PATH _ FORMAT)"]
			)
		       ("bibtex" :follow org-bibtex-open :store 
		       org-bibtex-store-link)
		       ("elfeed" :follow elfeed-link-open :store 
		       elfeed-link-store-link)
		       ("shell" :follow org-link--open-shell)
		       ("news" :follow
			#[514 "\301\300\302Q\"\207" ["news" 
                         browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("mailto" :follow
			#[514 "\301\300\302Q\"\207" ["mailto" 
                         browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("https" :follow
			#[514 "\301\300\302Q\"\207" ["https" 
                         browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("http" :follow
			#[514 "\301\300\302Q\"\207" ["http" 
                         browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("ftp" :follow
			#[514 "\301\300\302Q\"\207" ["ftp" 
                         browse-url ":"] 6
			  "\n\n(fn URL ARG)"]
			)
		       ("help" :follow org-link--open-help)
		       ("file" :complete org-link-complete-file)
		       ("elisp" :follow org-link--open-elisp)
		       ("doi" :follow doi-link-menu :export
			#[(doi desc format)
			  "\b\304\267\202 \300\305 
			  \n\v\206\0\306\nP$\207\300\307 
			  \n\v\206\0\306\nP$\207\310\207"
			  [format
			   
			   doi-utils-dx-doi-org-url
			   
			   doi
			   
			   desc
			   
			   #s
			   
			   (hash-table
			    
																    
																      
																	   
																	       
																					
			    size
			    
																    
																      
																	   
																	       
																					
			    2
			    
																    
																      
																	   
																	       
																					
			    test
			    
																    
																      
																	   
																	       
																					
			    eq
			    
																    
																      
																	   
																	       
																					
			    rehash-size
			    
																    
																      
																	   
																	       
																					
			    1.5
			    
																    
																      
																	   
																	       
																					
			    rehash-threshold
			    
																    
																      
																	   
																	       
																					
			    0.8125
			    
																    
																      
																	   
																	       
																					
			    purecopy
			    
																    
																      
																	   
																	       
																					
			    t
			    
																    
																      
																	   
																	       
																					
			    data
			    
																    
																      
																	   
																	       
																					
			    (html 6 latex 19)
			    
																    
																      
																	   
																	       
																					
			    )
			   
			   "<a href=\"%s%s\">%s</a>" "doi:" 
			   "\\href{%s%s}{%s}" nil]
			  6]
			)
		       )
 org-agenda-skip-scheduled-if-done t
 org-latex-format-headline-function 
 'org-latex-format-headline-default-function
 org-agenda-start-with-follow-mode t
 org-capture-templates '(("t" "New task" entry (file+headline 
 gtd-file "Inbox") "* TODO %i%?")
			 ("e" "Email action" entry (file+headline 
			 gtd-file "Inbox")
			  "* TODO %a\n%?")
			 ("w" "Email waiting" entry (file+headline 
			 gtd-file "Inbox")
			  "* WAITING %a\n%?")
			 ("n" "New note" item (file+headline 
			 "index.org" "Inbox") "- %?"))
 org-latex-logfiles-extensions '("lof" "lot" "tex~" "aux" "idx" 
 "log" "out" "toc" "nav" "snm"
				 "vrb" "dvi" "fdb_latexmk" "blg" 
				 "brf" "fls" "entoc" "ps"
				 "spl" "bbl" "tex" "bcf")
 org-link-elisp-confirm-function nil
 org-roam-db-autosync-mode t
 org-roam-dailies-capture-templates '(("d" "default" entry "* %?" 
 :if-new
				       (file+head 
				       "%<%Y-%m-%d>.org"
					"#+title: %<%Y-%m-%d: 
					>\n#+filetags: 
					:Diary:\n\n")
				       )
				      )
 org-latex-format-inlinetask-function 
 'org-latex-format-inlinetask-default-function
 org-html-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME 
 CONTENTS)"]
 org-superstar-special-todo-items t
 org-image-actual-width '(450)
 org-ref-get-pdf-filename-function 
 'org-ref-get-pdf-filename-helm-bibtex
 org-roam-directory "/home/peter/Documents/org-roam/"
 org-latex-classes '(("apa6"
		      "\\documentclass[a4paper, jou, 11pt]{apa6}\n 
		      \\usepackage[nodoi]{apacite}\n 
		      \\usepackage[british]{babel}\n 
		      \\usepackage{inputenc}\n 
		      \\usepackage{amsmath}\n 
		      \\usepackage{graphicx}\n 
		      \\usepackage{csquotes}\n 
		      \\usepackage[hyphens]{url}\n 
		      \\usepackage[T1]{fontenc}\n 
		      \\usepackage{lmodern}\n 
		      \\usepackage{hyperref}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}"))
		     ("TaylorFrancis"
		      "\\documentclass[largeformat]{interact}\n 
		      \\usepackage{hyperref}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("magictrick"
		      "\\documentclass[11pt, a4paper, twocolumn, 
		      twoside]{article}\n \\usepackage{ccicons}\n 
		      \\usepackage{pdfpages}\n 
		      \\usepackage{times}\n \\usepackage{helvet}\n 
		      \\usepackage{geometry}\n \\geometry{a4paper, 
		      total={170mm,250mm}, left=20mm, top=30mm}\n 
		      % header 2008 x 332 px\n 
		      \\usepackage{titlesec}\n 
		      \\titleformat{\\section}\n 
		      {\\bfseries}{\\thesection}{1em}{}\n 
		      \\titleformat{\\subsection}\n 
		      {\\itshape}{\\thesection}{1em}{}\n 
		      \\usepackage{fancyhdr}\n 
		      \\usepackage[font={small, it}, 
		      labelformat=empty]{caption}\n 
		      \\usepackage[hidelinks]{hyperref}\n 
		      \\pagestyle{fancy}\n 
		      \\renewcommand{\\headrulewidth}{0pt}\n 
		      \\renewcommand{\\footrulewidth}{0pt}\n 
		      \\setlength{\\parskip}{1em}\n 
		      \\renewcommand{\\baselinestretch}{1.1}\n 
		      \\setlength\\headheight{100.0pt}\n 
		      \\addtolength{\\textheight}{-100.0pt}\n 
		      \\fancyhead[LO]{\\Large{\\textsf{Magic 
		      Perspectives Presents}} 
		      \\includegraphics[width=\\textwidth]{header}}\n 
		      \\fancyhead[LE]{\\includegraphics[width=0.5\\textwidth]{header}}\n 
		      \\lfoot{Peter Prevos}\n 
		      \\rfoot{\\href{https://magicperspectives.net}{magicperspectives.net}}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}"))
		     ("Springer"
		      "\\documentclass[natbib]{svjour3}\n 
		      \\usepackage{hyperref}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("trade"
		      "\n \\documentclass[11pt, twoside]{memoir}\n 
		      \\setstocksize{9in}{6in}\n 
		      \\settrimmedsize{\\stockheight}{\\stockwidth}{*}\n 
		      \\setlrmarginsandblock{2cm}{2cm}{*} % Left 
		      and right margin\n 
		      \\setulmarginsandblock{2cm}{2cm}{*} % Upper 
		      and lower margin\n \\checkandfixthelayout\n 
		      \\setcounter{tocdepth}{0}\n 
		      \\OnehalfSpacing\n \\usepackage{times}\n 
		      \\chapterstyle{bianchi}\n 
		      \\setsecheadstyle{\\normalfont \\raggedright 
		      \\textbf}\n 
		      \\setsubsecheadstyle{\\normalfont 
		      \\raggedright \\emph}\n 
		      \\setsubsubsecheadstyle{\\normalfont\\centering}\n 
		      \\usepackage[font={small, it}]{caption}\n 
		      \\usepackage{subcaption}\n 
		      \\captionsetup[subfigure]{justification=centering}\n 
		      \\usepackage{pdfpages}\n 
		      \\pagestyle{myheadings}\n 
		      \\usepackage{ccicons}\n 
		      \\usepackage{nicefrac}\n 
		      \\usepackage[authoryear]{natbib}\n 
		      \\bibliographystyle{apalike}\n 
		      \\usepackage{nohyperref}\n "
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("ebook"
		      "\\documentclass[11pt, oneside]{memoir}\n 
		      \\setstocksize{9in}{6in}\n 
		      \\settrimmedsize{\\stockheight}{\\stockwidth}{*}\n 
		      \\setlrmarginsandblock{2cm}{2cm}{*} % Left 
		      and right margin\n 
		      \\setulmarginsandblock{2cm}{2cm}{*} % Upper 
		      and lower margin\n \\checkandfixthelayout\n 
		      \\usepackage{times}\n \\OnehalfSpacing\n 
		      \\usepackage[authoryear]{natbib}\n 
		      \\bibliographystyle{apalike}\n 
		      \\setlength{\\bibsep}{1pt}\n 
		      \\usepackage[raggedright]{sidecap}\n 
		      \\setsecheadstyle{\\normalfont \\raggedright 
		      \\textbf}\n 
		      \\setsubsecheadstyle{\\normalfont 
		      \\raggedright \\emph}\n 
		      \\usepackage{subcaption} \n 
		      \\usepackage[font={small, it}]{caption}\n 
		      \\captionsetup[subfigure]{justification=centering}\n 
		      \\usepackage{pdfpages}\n 
		      \\usepackage[unicode=true,\n 
		      bookmarks=true,bookmarksnumbered=false,bookmarksopen=true,\n 
		      bookmarksopenlevel=1, 
		      breaklinks=true,pdfborder={0 0 
		      0},backref=false,colorlinks=false,pdfborderstyle={/S/U/W 
		      .5}, allbordercolors={.8 .8 .8}]{hyperref}\n 
		      \\pagestyle{myheadings}\n 
		      \\setcounter{tocdepth}{0}\n 
		      \\usepackage{ccicons}\n 
		      \\usepackage{nicefrac}\n "
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}"))
		     ("article" "\\documentclass[11pt]{article}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" 
		      . "\\subparagraph*{%s}"))
		     ("report" "\\documentclass[11pt]{report}" 
		     ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}"))
		     ("book" "\\documentclass[11pt]{book}" 
		     ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" 
		      . "\\subsubsection*{%s}"))
		     )
 org-html-format-headline-function 
 'org-html-format-headline-default-function
 org-confirm-babel-evaluate nil
 org-ref-cite-onclick-function 'org-ref-cite-click-helm
 org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil 
 author:nil email:nil \\n:t"
 org-agenda-custom-commands '(("n" "Netherlands" tags-todo "NL")
			      ("o" "Outsource" tags-todo 
			      "outsource")
			      ("c" "Coliban Water"
			       ((agenda ""
				 ((org-agenda-span 7) 
				 (org-agenda-start-on-weekday 1)
				  (org-agenda-files
				   '("~/Documents/org-roam/coliban-water.org"))
				  (org-agenda-sorting-strategy 
				  '(priority-up)))
				 )
				(todo "NEXT"
				 ((org-agenda-files
				   '("~/Documents/org-roam/coliban-water.org"))
				  )
				 )
				(todo "WAITING"
				 ((org-agenda-files
				   '("~/Documents/org-roam/coliban-water.org"))
				  )
				 )
				)
			       )
			      ("p" "Priorities" tags-todo 
			      "+PRIORITY=\"A\"")
			      ("h" "Third Hemisphere"
			       ((agenda ""
				 ((org-agenda-span 2) 
				 (org-agenda-start-on-weekday nil)
				  (org-agenda-files 
				  '("~/Documents/org-roam/gtd.org"))
				  (org-agenda-sorting-strategy 
				  '(priority-up)))
				 )
				(todo "NEXT"
				 ((org-agenda-files 
				 '("~/Documents/org-roam/gtd.org"))))
				(todo "WAITING"
				 ((org-agenda-files 
				 '("~/Documents/org-roam/gtd.org"))))
				(stuck ""))
			       )
			      )
 org-directory "/home/peter/Documents/org-roam/"
 org-link-from-user-regexp "\\<peter@xps15-7590\\>\\|\\<Peter 
 Prevos\\>"
 org-ref-notes-function 'orb-edit-notes
 org-agenda-skip-deadline-if-done t
 org-default-notes-file "/home/peter/Documents/org-roam/inbox.org"
 )


^ permalink raw reply	[relevance 1%]

* Re: Smart quotes not working correctly with single quotes
  @ 2021-05-29 21:35  7%         ` Andreas Gösele
  0 siblings, 0 replies; 200+ results
From: Andreas Gösele @ 2021-05-29 21:35 UTC (permalink / raw)
  To: emacs-orgmode

Hi,

thanks to Albert for pointing me to pandoc-quotes.lua.

It doesn't take care of apostrophes so I wrote my own very simple pandoc
lua filter:

 text = require 'text'
 function Str (s)
   s.text = pandoc.pipe("sed", {"-e","s/'/’/"}, s.text)
   return s
 end

Together with pandoc-quotes.lua and "-M lang=de" this gives the desired
result for odt and html.

For latex there was no problem with the apostrophes, but for some reason
(I don't understand) pandoc-quotes.lua with lang=de translates closing
quotes into "``" and "`" instead of "“" and "‘". (The opening quotes are
correct and in pandoc-quotes.lua the "de" entry correctly has "“" and
"‘".) This can lead to something like "```" if inner quotes are
immediately followed by outer quotes which LaTeX translates to "“‘"
instead of "‘“".

To solve this I created a meta file with:

---
quot-marks:
    - „
    - ​“
    - ‚
    - ‘
...

(The important thing being that there is a unicode "ZERO WIDTH SPACE"
(U+200B) in front of the second entry.)

I also put \DeclareUnicodeCharacter{200B}{{\hskip 0pt}} into
default.latex.

Using the meta-file with pandoc-quotes.lua and "-V lang=de" leads to
correctly nested quotes also for latex.

Thanks again to everybody!

Andreas

Andreas Gösele <agoesele@sju.edu> writes:

> Albert Krewinkel <albert+org-mode@zeitkraut.de> writes:
>
>> Andreas Gösele <agoesele@sju.edu> writes:
>>
>>> [...] I tried to convert the LaTeX document with pandoc, tex4h and
>>> latex2html to odt and html but none of them produces the correct
>>> output.
>>>
>>> So I'm wondering whether there is any way to make org export to
>>> recognize single quotes also outside from double quote. It should be
>>> possible as inner quotes is not the only use of simple quotes.
>>
>> I apologize for the non-Emacs solution, but you can use pandoc in
>> combination with the following Lua filter to get the desired result:
>> https://github.com/pandoc/lua-filters/tree/master/pandoc-quotes.lua
>> For LaTeX output, you can also pass -Vcsquotes as a parameter to force
>> pandoc to make use of the csquotes package. Both should give you the
>> desired results.
>
> Thanks for the suggestion. I would be happy to use pandoc.
>
> I tried it and it works well for quotes (double and single). But the
> apostrophe only is correctly treated if I convert to LaTeX/PDF. (That's
> because LaTeX transforms the "typewriter apostrophe" into the correct
> typographic apostrophe.)
>
> From:
>
>  #+LANGUAGE: de
>  #+OPTIONS: ':t
>
>  #+OPTIONS: toc:nil
>  It's a 'test'.
>
> I get for html/odt:
>
>  It's a ‚test‘.
>
> But I should get:
>
>  It’s a ‚test‘.
>
> Directly using the org export I get:
>
>  It’s a ’test’.
>
> So with pandoc and the Lua filter the single quotes are correct, with
> the direct export from org the apostrophe is correct.
>
> Is there a way with pandoc to get correct quotes and apostrophes?
>
> Thanks again!
>
> Andreas


^ permalink raw reply	[relevance 7%]

* Re: Dealing with wide labels in description environment
  2021-01-22 11:20  0% ` Juan Manuel Macías
@ 2021-01-22 12:37  0%   ` Loris Bennett
  0 siblings, 0 replies; 200+ results
From: Loris Bennett @ 2021-01-22 12:37 UTC (permalink / raw)
  To: Juan Manuel Macías; +Cc: orgmode

Hi Juan,

Juan Manuel Macías <maciaschain@posteo.net> writes:

> Hello,
>
> "Loris Bennett" <loris.bennett@fu-berlin.de> writes:
>
>> I have tried tweaking options such as labelindent and labelwidth in a
>> somewhat haphazard manner with, say,
>>  
>>   #+attr_latex: :options [labelindent=0pt, labelwidth=10ex] 
>>
>> but most of my attempts seem to have the main effect of just shifting
>> the whole list to the right without right-justifying the labels.
>
> The question is more on the side of LaTeX, and the enumitem package
> (which you must have loaded for those options. See:
> https://www.ctan.org/pkg/enumitem). For the effect you are looking for
> you can try this (for horizontal lengths, it is better to use 'em' than
> 'ex):

Yes, of course - using Org for a decade so or has helped me avoid and thus
forget about certain LaTeX details.

> #+LATEX_HEADER: \usepackage{enumitem}
>
> #+attr_latex: :options
> [labelindent=0em,itemindent=0em,align=right,labelwidth=10em,labelsep=.5em,leftmargin=15.5em]
> - short label :: this looks fine
> - very annoying overly long label :: Lorem ipsum dolor sit amet, consectetuer adipiscing
>   elit. Donec hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam nisl,
>   tincidunt et, mattis eget, convallis nec, purus. Cum sociis natoque penatibus et magnis
>   dis parturient montes, nascetur ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam
>   tristique diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam vestibulum
>   accumsan nisl.

Thank, that's what I needed - 'leftmargin' seems to be the main thing
that was missing.  

Gruß

Loris

-- 
This signature is currently under construction.


^ permalink raw reply	[relevance 0%]

* Re: Dealing with wide labels in description environment
  2021-01-22  9:20  8% Dealing with wide labels in description environment Loris Bennett
@ 2021-01-22 11:20  0% ` Juan Manuel Macías
  2021-01-22 12:37  0%   ` Loris Bennett
  0 siblings, 1 reply; 200+ results
From: Juan Manuel Macías @ 2021-01-22 11:20 UTC (permalink / raw)
  To: Loris Bennett; +Cc: orgmode

Hello,

"Loris Bennett" <loris.bennett@fu-berlin.de> writes:

> I have tried tweaking options such as labelindent and labelwidth in a
> somewhat haphazard manner with, say,
>  
>   #+attr_latex: :options [labelindent=0pt, labelwidth=10ex] 
>
> but most of my attempts seem to have the main effect of just shifting
> the whole list to the right without right-justifying the labels.

The question is more on the side of LaTeX, and the enumitem package
(which you must have loaded for those options. See:
https://www.ctan.org/pkg/enumitem). For the effect you are looking for
you can try this (for horizontal lengths, it is better to use 'em' than
'ex):

#+LATEX_HEADER: \usepackage{enumitem}

#+attr_latex: :options [labelindent=0em,itemindent=0em,align=right,labelwidth=10em,labelsep=.5em,leftmargin=15.5em]
- short label :: this looks fine
- very annoying overly long label :: Lorem ipsum dolor sit amet, consectetuer adipiscing
  elit. Donec hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam nisl,
  tincidunt et, mattis eget, convallis nec, purus. Cum sociis natoque penatibus et magnis
  dis parturient montes, nascetur ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam
  tristique diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam vestibulum
  accumsan nisl.

Regards,

Juan Manuel 


^ permalink raw reply	[relevance 0%]

* Dealing with wide labels in description environment
@ 2021-01-22  9:20  8% Loris Bennett
  2021-01-22 11:20  0% ` Juan Manuel Macías
  0 siblings, 1 reply; 200+ results
From: Loris Bennett @ 2021-01-22  9:20 UTC (permalink / raw)
  To: Org Mode Mailing List

Hi,

I am exporting to PDF via LaTeX and have the following

 - short label :: this looks fine
 - very annoying overly long label :: this doesn't 

on export, the long label protrudes into the definitions column.

I have tried tweaking options such as labelindent and labelwidth in a
somewhat haphazard manner with, say,
 
  #+attr_latex: :options [labelindent=0pt, labelwidth=10ex] 

but most of my attempts seem to have the main effect of just shifting
the whole list to the right without right-justifying the labels.

Does anyone know how to do this properly?

Cheers,

Loris

-- 
This signature is currently under construction.


^ permalink raw reply	[relevance 8%]

* Re: basic org questions
  2020-09-16 16:32  0%           ` Stefan Nobis
@ 2020-09-16 22:53  8%             ` Emanuel Berg via General discussions about Org-mode.
  0 siblings, 0 replies; 200+ results
From: Emanuel Berg via General discussions about Org-mode. @ 2020-09-16 22:53 UTC (permalink / raw)
  To: emacs-orgmode

Stefan Nobis wrote:

>> #+latex_header: \setlength{\parindent}{0pt}
>> #+latex_header: \setlength{\parskip}{\baselineskip}
>
> Better use
>
> #+latex_header: \usepackage{parskip}
>
> as this package has less bad side-effects on other
> parts of the document than setting these far-reaching
> lengths directly.

OK, but the values still ned to be specified, right?

Or you mean all three:

  #+latex_header: \usepackage{parskip}
  #+latex_header: \parskip   1.5ex
  #+latex_header: \parindent   0pt

?

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal



^ permalink raw reply	[relevance 8%]

* Re: basic org questions
  2020-09-16 22:28  0%         ` Tim Cross
@ 2020-09-16 22:31  0%           ` Emanuel Berg via General discussions about Org-mode.
  0 siblings, 0 replies; 200+ results
From: Emanuel Berg via General discussions about Org-mode. @ 2020-09-16 22:31 UTC (permalink / raw)
  To: emacs-orgmode

Tim Cross wrote:

>> #+latex_header: \parskip   1.5ex
>> #+latex_header: \parindent   0pt
>
> Note that I agree with the other post recommending
> using the parskip package as a better solution.
> I had forgotten about that package when I posted
> the above, which is really just a dirty hack.

Yeah? Looks OK to me :)

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal



^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16 22:11  8%       ` Emanuel Berg via General discussions about Org-mode.
@ 2020-09-16 22:28  0%         ` Tim Cross
  2020-09-16 22:31  0%           ` Emanuel Berg via General discussions about Org-mode.
  0 siblings, 1 reply; 200+ results
From: Tim Cross @ 2020-09-16 22:28 UTC (permalink / raw)
  To: emacs-orgmode


Emanuel Berg via General discussions about Org-mode. <emacs-orgmode@gnu.org> writes:

> Tim Cross wrote:
>
>> #+latex_header: \parskip 1.5ex
>
> Got it! Thanks! Now it works, with:
>
>   #+latex_header: \parskip   1.5ex
>   #+latex_header: \parindent   0pt

Note that I agree with the other post recommending using the parskip
package as a better solution. I had forgotten about that package when I
posted the above, which is really just a dirty hack.

Tim

-- 
Tim Cross


^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16  4:31  0%     ` Tim Cross
@ 2020-09-16 22:11  8%       ` Emanuel Berg via General discussions about Org-mode.
  2020-09-16 22:28  0%         ` Tim Cross
  0 siblings, 1 reply; 200+ results
From: Emanuel Berg via General discussions about Org-mode. @ 2020-09-16 22:11 UTC (permalink / raw)
  To: emacs-orgmode

Tim Cross wrote:

> #+latex_header: \parskip 1.5ex

Got it! Thanks! Now it works, with:

  #+latex_header: \parskip   1.5ex
  #+latex_header: \parindent   0pt

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal



^ permalink raw reply	[relevance 8%]

* Re: basic org questions
  2020-09-16 13:48  8%         ` Eric S Fraga
@ 2020-09-16 16:32  0%           ` Stefan Nobis
  2020-09-16 22:53  8%             ` Emanuel Berg via General discussions about Org-mode.
  0 siblings, 1 reply; 200+ results
From: Stefan Nobis @ 2020-09-16 16:32 UTC (permalink / raw)
  To: emacs-orgmode

Eric S Fraga <e.fraga@ucl.ac.uk> writes:

> #+latex_header: \setlength{\parindent}{0pt}
> #+latex_header: \setlength{\parskip}{\baselineskip}

Better use

#+latex_header: \usepackage{parskip}

as this package has less bad side-effects on other parts of the
document than setting these far-reaching lengths directly.

But otherwise I second your recommendation to not use this style of
marking paragraphs if not absolutely required.

-- 
Until the next mail...,
Stefan.


^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16  4:13  0%       ` Emanuel Berg
@ 2020-09-16 13:48  8%         ` Eric S Fraga
  2020-09-16 16:32  0%           ` Stefan Nobis
  0 siblings, 1 reply; 200+ results
From: Eric S Fraga @ 2020-09-16 13:48 UTC (permalink / raw)
  To: TEC, emacs-orgmode

On Wednesday, 16 Sep 2020 at 06:13, Emanuel Berg wrote:
> TEC wrote:
>
>> #+begin_src latex
>> \setlength{\parindent}{0pt}
>> \setlength{\parskip}{\baselineskip}
>> #+end_src
>
> Also, that doesn't work. Put it in the document, new
> PDF, looks the same.

Try

#+latex_header: \setlength{\parindent}{0pt}
#+latex_header: \setlength{\parskip}{\baselineskip}

instead.  This works for me but only use it when required by the
recipient of the document (e.g. camera ready conference
proceedings).  Otherwise, I always go with LaTeX defaults as those were
designed by people that understood typesetting (unlike your average
conference organizer unfortunately).

-- 
: Eric S Fraga via Emacs 28.0.50, Org release_9.3.7-725-g7bc18e


^ permalink raw reply	[relevance 8%]

* Re: basic org questions
  2020-09-16  1:58  0%   ` Emanuel Berg via General discussions about Org-mode.
                       ` (2 preceding siblings ...)
  2020-09-16  6:54  0%     ` tomas
@ 2020-09-16  7:37  0%     ` Stefan Nobis
  3 siblings, 0 replies; 200+ results
From: Stefan Nobis @ 2020-09-16  7:37 UTC (permalink / raw)
  To: emacs-orgmode

Emanuel Berg via "General discussions about Org-mode."
<emacs-orgmode@gnu.org> writes:

> Tim Cross wrote:

>> #+latex_class: korma-article

> user-error: Unknown LaTeX class ‘korma-article’

>> #+latex_header:  \setlength{\parindent}{0pt}

> Yes, that's removed the indentation but didn't insert
> a blank line...

First of all: You don't want this. :)

Marking paragraphs by blank lines and without indentation is deemed
less readable (see for example section 3.10 "Marking Paragraphs" in
https://komascript.de/~mkohm/scrguien.pdf).

But if you really insist on using this style, still the variant of
setting the length parindent and parskip is considered bad practise.
These are very fundamental values for LaTeX and influence a lot more
that just the space between paragraphs. A much better solution would
be to use the package =parskip= (just add "\usepackage{parskip}" to
the preamble of the LaTeX document or add "#+LATEX_HEADER:
\usepackage{parskip}" to the preamble of the Org document).

If you want to customize the Org LaTeX export more globally, you can
put something like this in your Emacs init.el:

#+begin_src elisp
(add-to-list 'org-latex-classes
               '("koma-article"
                 "\\documentclass[a4paper, pagesize, headings=normal, version=last]{scrartcl}"
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                 ("\\paragraph{%s}" . "\\paragraph*{%s}")
                 ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))

(setq org-latex-default-class "koma-article")

(setq org-latex-packages-alist
        '(("" "unicode-math" t ("lualatex" "xelatex"))
          ("" "caption" nil)
          ("" "booktabs" t)))
#+end_src

In the case of the document classes of the Koma world, you have quite
some options for paragraph formatting. If you still insist on your
style of paragraph markings, you may add "parskip=full" to the
global options of the documentclass.

With the above settings, you globally define your preferred LaTeX
documentclass and some global settings as well as add some additionals
packages that are used on every LaTeX export done via Org. So you do
not have to put anything special in the individual Org documents but
the pure content (at the cost that the same Org document may produce a
different output on other Emacs installations with different global
settings).

For more details on what can be configured see
https://orgmode.org/manual/Exporting.html#Exporting. The options there
are mostly presented as in-document settings but most if not all of
them may also be set in some way globally via Emacs init.

-- 
Until the next mail...,
Stefan.


^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16  4:11  0%       ` Emanuel Berg
@ 2020-09-16  6:56  0%         ` tomas
  0 siblings, 0 replies; 200+ results
From: tomas @ 2020-09-16  6:56 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 505 bytes --]

On Wed, Sep 16, 2020 at 06:11:52AM +0200, Emanuel Berg wrote:
> TEC wrote:
> 
> > #+begin_src latex
> > \setlength{\parindent}{0pt}
> > \setlength{\parskip}{\baselineskip}
> > #+end_src
> 
> I know this commands well from my LaTeX projects,
> but I'm gonna use LaTeX anyway, what's the use of
> using org-mode?

LaTeX is (as you might know already ;-) for typesetting. Org
is for organising information.

Sometimes you want to typeset a representation of that information.

Cheers
 - t

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16  1:58  0%   ` Emanuel Berg via General discussions about Org-mode.
  2020-09-16  3:46  8%     ` TEC
  2020-09-16  4:31  0%     ` Tim Cross
@ 2020-09-16  6:54  0%     ` tomas
  2020-09-16  7:37  0%     ` Stefan Nobis
  3 siblings, 0 replies; 200+ results
From: tomas @ 2020-09-16  6:54 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 958 bytes --]

On Wed, Sep 16, 2020 at 03:58:17AM +0200, Emanuel Berg via General discussions about Org-mode. wrote:
> Tim Cross wrote:
> 
> > #+latex_class: korma-article
> 
> user-error: Unknown LaTeX class ‘korma-article’

This might have been a typo: there is a family of LaTeX classes called
"koma" (not "korma", that's rather a family of Indian dishes ;-)

That said, I fail to find a korma-article.cls. So perhaps this wasn't
meant /literally/ by Tim, but rather a placeholder.

> > #+latex_header:  \setlength{\parindent}{0pt}
> 
> Yes, that's removed the indentation but didn't insert
> a blank line...

I think Tim is just furnishing examples, not a complete solution.

LaTeX is a world unto itself, and to fine-tune the results of your
LaTeX exporter (the PDF exporter is just a little appendix on that),
you'll have to dive a bit into that.

Or just ask around here, but best with concrete, little goals each
time.

Cheers
 - t

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16  3:46  8%     ` TEC
@ 2020-09-16  4:11  0%       ` Emanuel Berg
  2020-09-16  6:56  0%         ` tomas
  2020-09-16  4:13  0%       ` Emanuel Berg
  1 sibling, 1 reply; 200+ results
From: Emanuel Berg @ 2020-09-16  4:11 UTC (permalink / raw)
  To: TEC; +Cc: emacs-orgmode

TEC wrote:

> #+begin_src latex
> \setlength{\parindent}{0pt}
> \setlength{\parskip}{\baselineskip}
> #+end_src

I know this commands well from my LaTeX projects,
but I'm gonna use LaTeX anyway, what's the use of
using org-mode?

Is this the org-mode that people have been praising
for like a decade or so? You get to do LaTeX
all over?

And even for the most basic tasks like configuring
how a paragraph will look?

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal


^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16  3:46  8%     ` TEC
  2020-09-16  4:11  0%       ` Emanuel Berg
@ 2020-09-16  4:13  0%       ` Emanuel Berg
  2020-09-16 13:48  8%         ` Eric S Fraga
  1 sibling, 1 reply; 200+ results
From: Emanuel Berg @ 2020-09-16  4:13 UTC (permalink / raw)
  To: TEC; +Cc: emacs-orgmode

TEC wrote:

> #+begin_src latex
> \setlength{\parindent}{0pt}
> \setlength{\parskip}{\baselineskip}
> #+end_src

Also, that doesn't work. Put it in the document, new
PDF, looks the same.

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal


^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16  1:58  0%   ` Emanuel Berg via General discussions about Org-mode.
  2020-09-16  3:46  8%     ` TEC
@ 2020-09-16  4:31  0%     ` Tim Cross
  2020-09-16 22:11  8%       ` Emanuel Berg via General discussions about Org-mode.
  2020-09-16  6:54  0%     ` tomas
  2020-09-16  7:37  0%     ` Stefan Nobis
  3 siblings, 1 reply; 200+ results
From: Tim Cross @ 2020-09-16  4:31 UTC (permalink / raw)
  To: emacs-orgmode


Emanuel Berg via General discussions about Org-mode. <emacs-orgmode@gnu.org> writes:

> Tim Cross wrote:
>
>> #+latex_class: korma-article
>
> user-error: Unknown LaTeX class ‘korma-article’

That probably indicates you have not got the necessary Latex packages
installed. It was mainly an example of using a different document class
style (there are many). Depending on what platform your on, some of
these additional classes are in a separate package, often called
something like latex-extra or latex-styles-extra or similar.

>
>> #+latex_header:  \setlength{\parindent}{0pt}
>
> Yes, that's removed the indentation but didn't insert
> a blank line...

#+latex_header: \parskip 1.5ex 

might work. Again, this stuff is controlled by the specific latex
document class your using. When you need to make 'tweaks' like this,
google latex commands and then use things like #+latex_header: to set
them. 

-- 
Tim Cross


^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  2020-09-16  1:58  0%   ` Emanuel Berg via General discussions about Org-mode.
@ 2020-09-16  3:46  8%     ` TEC
  2020-09-16  4:11  0%       ` Emanuel Berg
  2020-09-16  4:13  0%       ` Emanuel Berg
  2020-09-16  4:31  0%     ` Tim Cross
                       ` (2 subsequent siblings)
  3 siblings, 2 replies; 200+ results
From: TEC @ 2020-09-16  3:46 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-orgmode


Emanuel Berg via General discussions about Org-mode. <emacs-orgmode@gnu.org> writes:

> user-error: Unknown LaTeX class ‘korma-article’

This is just because the class has to be defined in =org-latex-classes=
(see the doctring for info).
By default it contains:
 - beamer
 - article
 - report
 - book

>> #+latex_header:  \setlength{\parindent}{0pt}
>
> Yes, that's removed the indentation but didn't insert
> a blank line...

This is getting into LaTeX, not Org, but you need to do two things:
 1. Remove indent
 2. Set parskip to the height of a line

i.e.
#+begin_src latex
\setlength{\parindent}{0pt}
\setlength{\parskip}{\baselineskip}
#+end_src

You can add a number before =\baselineskip= to 'stretch' that length.
E.g. for half a line =0.5\baselineskip=.

Hope that helps,

Timothy.


^ permalink raw reply	[relevance 8%]

* Re: basic org questions
  2020-09-16  0:04  3% ` Tim Cross
@ 2020-09-16  1:58  0%   ` Emanuel Berg via General discussions about Org-mode.
  2020-09-16  3:46  8%     ` TEC
                       ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From: Emanuel Berg via General discussions about Org-mode. @ 2020-09-16  1:58 UTC (permalink / raw)
  To: emacs-orgmode

Tim Cross wrote:

> #+latex_class: korma-article

user-error: Unknown LaTeX class ‘korma-article’

> #+latex_header:  \setlength{\parindent}{0pt}

Yes, that's removed the indentation but didn't insert
a blank line...

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal



^ permalink raw reply	[relevance 0%]

* Re: basic org questions
  @ 2020-09-16  0:04  3% ` Tim Cross
  2020-09-16  1:58  0%   ` Emanuel Berg via General discussions about Org-mode.
  0 siblings, 1 reply; 200+ results
From: Tim Cross @ 2020-09-16  0:04 UTC (permalink / raw)
  To: emacs-orgmode


Emanuel Berg via General discussions about Org-mode. <emacs-orgmode@gnu.org> writes:

> 1) How do I make a region italic?
>
> This does not fontify and does not show up as
> italic type:
>
> /En gång i tiden var även Spanien täckt av skog.
> En gammal berättelse menar att man i norra Spanien
> kunde hoppa upp på en apas rygg och ta sig ner till
> södra Spanien utan att klättra av en enda gång. Apan,
> underförstått, kunde hoppa från gren till gren genom
> hela halvön. Flyger man över Spanien idag ser man att
> det har gått åt ett och annat träd sen dess./
>
> /This/ works tho.
>
> 2) How do I have tables not appear centered
> by default, but left-aligned?
>
> 3) How do I have a new paragraph, as indicated by
>
> p1
>
> p2
>
> appear w/o indentation, but with a blank line between
> p1 and p2 (yes, exactly as stated, really).
>

It is important to understand the org mode architecture in order to
understand how/where to try and change/fix things to get specific
results. It is also very important to be clear about this architecture
when asking questions so that you can include the most relevant
information. 

Org has a multi-layered architecture. At the top is the org buffer where
you put your org text. This text supports markup and other text with
special  meaning which the Emacs editor will display in specific ways
using colours, fonts, overlays etc.

When you export an org file, the contents of the org file is
extracted and markup, options, 'special' text etc is mapped to the
equivalent 'concept' in the back end format. Sometimes, this translation
might involve multiple steps (e.g. for PDF the org text is translated
into Latex, which is then translated into pdf). Understanding this is
critical as all back ends are not the same and sometimes, the changes
you need to make need to be performed at the back end rather than within
the org file itself. For example, sometimes, a quick and easy change can
be achieved by manually editing the *.tex file generated when doing a
PDF export and other times, it may be necessary to define a whole new
document class in order to achieve the result you want (for example, I
defined a new entry for org-latex-classes called 'work' which added
additional Latex classes and macro definitions needed to support the
format documents had to have for my employer).  

All this means that you need to be explicit when asking a question
whether what you want is for the org buffer/file, the exported file and
what the exported format is.

As with many questions involving technology, you are often better off
explaining what your specific outcome is rather than on how to do
something as the latter is often asking how to do something to implement
what you think is the right solution when in fact a completely different
solution might be easier.

As an example, with your question about how to make a paragraph italic.
Do you want the text to appear italic in the org buffer or do you want
the PDF text which results from the export to be italic? Is it actually
critical that it is italic or do you just want to make sure that text is
rendered in such a way as to make it emphasised or stand out in the
final exported output?

If it is the latter, I would actually take a completely different
approach. Rather than trying to mark the whole paragraph as italic, I
would create a quoted block using #+begin_quote/#+end_quote. Each back
end will interpret this quoted block in its own way and render it
accordingly.

Another approach would be to use embedded latex in your document and
render the paragraph as a latex block using

\begin{em}
\end{em}

or

\begin{it}
\end{it}

The disadvantage of this approach is that your being very back end
specific in your org-file, so exporting to other formats may not work
well.

With respect to your question regarding table placement in your PDF,
have a look at the manual section on exporting and in particular, Latex
export options. There are a number of options you can add to your table
definition which will affect how the table is rendered or where it is
placed within the document. Note that Latex is a VERY powerful document
formatting system and it is VERY opinionated. Unlike MS Word and other
word processing systems, with Latex derived formatting, your almost
always better off leaving Latex to decide how to do things. With Latex,
you select a document style and run with that. Tables are notoriously
complex to get right and while you can achieve what you want, you will
likely need to read up on Latex and how it processes tables and you may
need to add or tweak the latex packages included by Org when it
generates the output in order to get the precise result you are after.
In your current case, you will likely be able to achieve your desired
result just using the ':float' or ':placement' commands (see the org
manual section on latex export).

With respect to your final question on paragraph indent for first line -
this is the default style for Latex documents. Different Latex document
styles have different paragraph styles, some of which do not indent the
first line. You can change the document style by adding a new latex
class. For example, many people prefer the Korma Article class for
documents over the default Latex Article class. You can change the class
in a number of ways including by adding a #+latex_class: header to the
org file. e.g.

#+latex_class: korma-article

Another alternative is to add an additional latex header argument. For
example, this may work to disable paragraph indentation

#+latex_header:  \setlength{\parindent}{0pt}

You can also prevent indentation of a specific paragraph by using the
latext

\noindent

command.

Note that the above is specific to exports based on Latex (such as PDF
export) and will not have effect on other export types.

If you really must heavily customise the PDF format, you have the power.
However, you will likely need to read up on Latex and the latex to pdf
process to understand how that works and then go back to the org manual
to work out the best ways to customise org to use the setting you want.
The key to success IMO is to be conservative here. Lots of research into
typography, text formatting etc has gone into the TeX/LaTeX system and
your generally best off going with their style decisions. Look for
alternative high-level document styles (such as the Korma, HiTech and
other styles) rather than try hacking existing styles as it will be
easier and give better results in the long term.

HTH

Tim

-- 
Tim Cross


^ permalink raw reply	[relevance 3%]

* Re: Bug: org-babel-expand-noweb-references is very slow [9.1.9 (release_9.1.9-65-g5e4542 @ /usr/share/emacs/26.3/lisp/org/)]
       [not found]             ` <87y2ujr198.fsf@nicolasgoaziou.fr>
@ 2020-01-08  2:18  1%           ` Vladimir Nikishkin
  0 siblings, 0 replies; 200+ results
From: Vladimir Nikishkin @ 2020-01-08  2:18 UTC (permalink / raw)
  To: Nicolas Goaziou, emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 6134 bytes --]

Hm...

I am attaching the file in which tangling is still slow.

The file is quite big, but that alone doesn't seem to be the reason
for slowliness (I tried adding 1M-long words in the random places of
the previous mwe).

You can see the result by C-c C-v C-v'ing the code block at the
"Ramanujan numbers" heading.

Below is the profiler report for C-c C-v C-v'ing.with the heaviest
blocks expanded:

- command-execute                                               52967  87%
 - call-interactively                                           52967  87%
  - funcall-interactively                                       52655  87%
   - org-babel-expand-src-block                                 52505  86%
    - org-babel-expand-noweb-references                         52424  86%
     - org-babel-get-src-block-info                             35019  57%
      - org-babel-params-from-properties                        28142  46%
       - org-entry-get                                          27753  45%
        - org-entry-get-with-inheritance                        27683  45%
         - org-up-heading-safe                                  26176  43%
          + org-back-to-heading                                   148   0%
            org-outline-level                                      73   0%
         + org--property-local-values                            1318   2%
         + org-back-to-heading                                     19   0%
           org--property-global-value                               6   0%
          member-ignore-case                                       22   0%
       + org-babel-parse-header-arguments                         359   0%
         #<compiled 0x2495bf1>                                      5   0%
      + org-src-coderef-format                                   2533   4%
      + org-element-context                                      2521   4%
      + org-babel--normalize-body                                1082   1%
      + mapcar                                                    473   0%
      + apply                                                     212   0%
        org-element-property                                        5   0%
     - org-in-commented-heading-p                               13928  23%
      - org-in-commented-heading-p                              10418  17%
       - org-up-heading-safe                                     9136  15%
          org-outline-level                                        22   0%
        + org-back-to-heading                                       7   0%
       + org-in-commented-heading-p                              1073   1%
       + org-heading-components                                    63   0%
       + org-before-first-heading-p                                45   0%
      + org-up-heading-safe                                      3147   5%
      + org-heading-components                                    142   0%
      + org-before-first-heading-p                                 95   0%
     + org-babel-active-location-p                               2594   4%
     + org-babel-ref-goto-headline-id                             139   0%
     + #<compiled 0x106c419>                                        1   0%
     + #<compiled 0x19f41bd>                                        1   0%
    + org-edit-src-code                                            50   0%
    + org-babel-get-src-block-info                                 21   0%
   + execute-extended-command                                     138   0%
   + org-edit-src-exit                                              5   0%
     scroll-down-command                                            4   0%
     mouse-select-window                                            2   0%
     scroll-up-command                                              1   0%
  + byte-code                                                     312   0%
+ ...                                                            7409  12%
+ timer-event-handler                                              54   0%
+ mouse-fixup-help-message                                         35   0%
+ flyspell-post-command-hook                                       22   0%
+ redisplay_internal (C function)                                  16   0%
+ tooltip-show-help                                                 4   0%
  undefined                                                         2   0%


вт, 7 янв. 2020 г. в 18:48, Nicolas Goaziou <mail@nicolasgoaziou.fr>:
>
> Hello,
>
> Vladimir Nikishkin <lockywolf@gmail.com> writes:
>
> > Well, now I'm using org from org's own melpa (9.3.8), and it's still very
> > slow.
> >
> > Is there something I'm missing?
>
> Possibly. With your initial ECM, pasted below for reference, and Org
> 9.3.1, the last block expands in around one second here.
>
> --8<---------------cut here---------------start------------->8---
> * Noweb expansion
> :PROPERTIES:
> :header-args:  :noweb yes
> :END:
>
> Hello, everyone.
>
> The mwe would be like:
>
> #+begin_src scheme :exports both :results output :noweb-ref bug1
> #+end_src
>
> #+begin_src scheme :exports both :results output :noweb-ref bug2
> #+end_src
>
> #+begin_src scheme :exports both :results output :noweb-ref bug3
> #+end_src
>
> #+begin_src scheme :exports both :results output :noweb-ref bug4
> #+end_src
>
> #+begin_src scheme :exports both :results output :noweb-ref bug5
> #+end_src
>
> #+begin_src scheme :exports both :results output :noweb-ref bug6
> #+end_src
>
> #+begin_src scheme :exports both :results output :noweb-ref bug7
> #+end_src
>
> #+begin_src scheme :exports both :results output :noweb-ref bug8
> #+end_src
>
> #+begin_src scheme :exports both :results output
> <<bug1>>
> <<bug2>>
> <<bug3>>
> <<bug4>>
> <<bug5>>
> <<bug6>>
> <<bug7>>
> <<bug8>>
> #+end_src
> --8<---------------cut here---------------end--------------->8---
>
> Regards,
>
> --
> Nicolas Goaziou



-- 
Yours sincerely, Vladimir Nikishkin

[-- Attachment #2: index.org --]
[-- Type: application/octet-stream, Size: 818063 bytes --]

# -*- mode: org; geiser-scheme-implementation: chibi;  -*-
# Time-stamp: <2020-01-07 18:24:54 lockywolf>
# Created   : [2019-08-18 Sun 20:11]
# Author    : lockywolf gmail.com

#+STARTUP: inlineimages
#+STARTUP: latexpreview
#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Euler
#+HTML_MATHJAX: cancel.js noErrors.js
#+OPTIONS: tex:imagemagick


* noweb + common
** Some common code blocks

** Setting chibi arguments. DANGEROUS                       :dangerous:elisp:

#+begin_src elisp :export both :results value
  (setq geiser-chibi-extra-command-line-parameters
     '("-m" "chibi" 
       "-m" "srfi 159" 
       "-m" "chibi ast" 
       "-m" "chibi time" 
       "-m" "srfi 27" 
       "-m" "chibi process" 
       "-m" "srfi 42" 
       "-m" "srfi 78" 
       "-m" "scheme list"
       "-m" "srfi 18"))
  (setq geiser-connection-timeout (* 2 geiser-connection-timeout))
#+end_src

#+RESULTS:
| -m | chibi | -m | srfi 159 | -m | chibi ast | -m | chibi time | -m | srfi 27 | -m | chibi process | -m | srfi 42 | -m | srfi 78 | -m | scheme list |

#+name: common
#+begin_src scheme :results output :exportss none
  (import (chibi ast))
  (import (chibi show))
   (define (disp sexp)
     (display sexp)
     (newline))
#+end_src

#+RESULTS: common

* SICP [59%]
:PROPERTIES:
:header-args: :noweb yes
:END:

** TODO Chapter 1: Building abstractions with procedures [57/61]
*** Snippet
 #+BEGIN_SRC scheme :exports both :results value :session
   (* (+ 2 (* 4 6))
      (+ 3 5 7))
 #+END_SRC

 #+RESULTS:
 : 390

*** Thought
 Tree accumulation is the process of computing a thing by traversing a tree.

*** DONE Figure 1.1 Tree representation, showing the value of each subcombination :graphviz:plantuml:
    CLOSED: [2019-08-20 Tue 14:35]
 For the sake of pedagogical clarity, I have formatted it as a picture.
 #+BEGIN_SRC plantuml :exports both :file figure-1-1-mm.png
 @startmindmap
 skinparam monochrome true
 +_ 390
 ++_ *
 ++_ 26
 +++_ +
 +++_ 2
 +++_ 24
 ++++_ *
 ++++_ 4
 ++++_ 6
 ++_ 15
 +++_ +
 +++_ 3
 +++_ 5
 +++_ 7
 @endmindmap
 #+END_SRC

 #+RESULTS:
 [[file:figure-1-1-mm.png]]

 # Then next line is the same diagram verbose, using DOT.
 #+begin_src plantuml :exports both :file figure-1-1-dot.png
 @startdot
 graph g {
	 node [shape=plaintext];
	 A1 [label="390"];

	 B1 [label="*"];
	 B2 [label="26"];
	 B3 [label="15"];

	 C1 [label="+"];
	 C2 [label="2"];
	 C3 [label="24"];

	 D1 [label="*"];
	 D2 [label="4"];
	 D3 [label="6"];

	 E1 [label="+"];
	 E2 [label="3"];
	 E3 [label="5"];
	 E4 [label="7"];

 // edges
	 A1 -- B1;
	 A1 -- B2;
	 A1 -- B3;
	
	 B2 -- C1;
	 B2 -- C2;
	 B2 -- C3;

	 C3 -- D1;
	 C3 -- D2;
	 C3 -- D3;

	 B3 -- E1;
	 B3 -- E2;
	 B3 -- E3;
	 B3 -- E4;

 //	B1 -> B3 [label="(g o f)'" tailport=s headport=s];

	 { rank=same; A1 }
	 { rank=same; B1 B2 B3 } 
	 { rank=same; C1 C2 C3 }
	 { rank=same; D1 D2 D3 }
	 { rank=same; E1 E2 E3 E4 }
 } 
 @enddot
 #+end_src 

 #+RESULTS:
 [[file:figure-1-1-dot.png]]

*** Snippet
#+name square
#+begin_src scheme :exports both :results value :session
  (define (square x) (* x x))
  (define (sum-of-squares x y)
    (+ (square x) (square y)))
  (sum-of-squares 3 4)
#+end_src

#+RESULTS:
: 25

*** DONE Exercise 1.1 Interpreter result
    CLOSED: [2019-08-20 Tue 14:23]
 #+begin_src scheme :exports both :results output :session
   (define (disp sexp)
     (display sexp)
     (newline))
   (disp 10)
   (disp (+ 2 3 4))
   (disp (- 9 1))
   (disp (/ 6 2))
   (disp (+ (* 2 4) (- 4 6)))
   (define a 3)
   (define b (+ a 1))
   (disp (+ a b (* a b)))
   (disp (= a b))
   (disp
    (if (and (> b a) (< b (* a b )))
	b
	a))
   (disp (cond ((= a 4) 6)
	((= b 4) (+ 6 7 a))
	(else 25)))
   (disp (+ 2 (if (< b a) b a)))
   (disp (* (cond ((> a b) a)
               ((< a b) b)
               (else -1)) 
            (+ a 1)))
 #+end_src

 #+RESULTS:
 #+begin_example
 10
 9
 8
 3
 6
 19
 #f
 4
 16
 5
 16
 #+end_example

*** DONE Exercise 1.2 Prefix form
    CLOSED: [2019-08-20 Tue 14:25]
 #+begin_src scheme :exports both :results value :session
 (/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5))))) (* 3 (- 6 2) (- 2 7)))
 #+end_src

 #+RESULTS:
 : -37/150

*** DONE Exercise 1.3 Sum of squares
    CLOSED: [2019-08-20 Tue 14:35]
 #+begin_src scheme :exports both :results value :session
 (define (sum-of-squares x y)
   (+ (square x) (square y)))
 (import (srfi 95))
 (define (sum-of-two-max a b c)
   (let ((num_list (sort (list a b c) (lambda (a b) (if (> a b) a b)))))
    (sum-of-squares (car num_list) (cadr num_list))))
 (sum-of-two-max 1 2 3)
 #+end_src

 #+RESULTS:
 : "Result (exception): {Exception #19 user \"undefined variable\" (sort) #<procedure sum-of-two-max> (#f . 41)}\nStack trace:\n  called from <anonymous> on line 813 of file /usr/lib64/chibi/init-7.scm\n  called from <anonymous> on line 280 of file /usr/lib64/chibi/init-7.scm\n  called from <anonymous> on line 1202 of file /usr/lib64/chibi/init-7.scm\n  called from <anonymous> on line 813 of file /usr/lib64/chibi/init-7.scm\n  called from sum-of-two-max on line 41\n  called from <anonymous> on line 813 of file /usr/lib64/chibi/init-7.scm\n  called from call-with-current-continuation on line 840 of file /usr/lib64/chibi/init-7.scm\n  called from <anonymous> on line 813 of file /usr/lib64/chibi/init-7.scm\n  called from <anonymous> on line 280 of file /usr/lib64/chibi/init-7.scm\n  called from <anonymous> on line 280 of file /usr/lib64/chibi/init-7.scm\n  called from <anonymous> on line 813 of file /usr/lib64/chibi/init-7.scm\n  called from call-with-current-continuation on line 840 of file /usr/lib64/chibi/init-7.scm\n  called from geiser:eval on line 25 of file /usr/lib64/chibi/scheme/misc-macros.scm\n"

*** DONE Exercise 1.4 Compound expressions
    CLOSED: [2019-08-20 Tue 14:39]
 #+begin_src scheme :exports both :results output :session
 (define (a-plus-abs-b a b)
   ((if (> b 0) + -) a b))
 (disp (a-plus-abs-b  3 4))
 (disp (a-plus-abs-b  3 -4))
 #+end_src

 #+RESULTS:
 : 7
 : 7

*** DONE Exercise 1.5 Ben's test
    CLOSED: [2019-08-20 Tue 14:50]
 #+begin_src scheme :exports both :results value
 (define (p) (p))
 (define (test x y)
   (if (= x 0) 0 y))
 (test 0 (p))
 #+end_src

 On my interpreter this code goes into an infinite recursion, which
 makes sense, I guess, since the second argument to (test) is evaluated
 before executing (test). However, if we only substitute /p/ into the
 application of test and try to traverse the tree depth-first, this
 code should be able to terminate successfully?

*** DONE Exercise 1.6 If is a special form
    CLOSED: [2019-08-21 Wed 14:05]
The problem with this Alyssa's (new-if) is that both arguments would
be computed, so this (new-if) would be either very inefficient or even
not working at all in the case when one of the arguments is
infeasible.
Consider:

#+begin_src scheme :exports both :results output :session
<<common>>
(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))
(define a 1)
(define b 0)
(disp (if (not (= b 0)) (/ a b) a))
(new-if (not (= b 0)) (/ a b) a)
#+end_src

#+RESULTS:
: 1
: {Exception #19 user "divide by zero" () #<procedure #f> (#f . 127)}

However, this issue can be solved using scheme macros.

#+begin_src scheme :exports both :results output :session
  <<common>>
  (define-syntax new-if
    (syntax-rules ()
      ( (new-if predicate then-clause else-clause)
	(cond (predicate then-clause)
	      (else else-clause))
      )
    )
  )
  (define a 1)
  (define b 0)
  (disp (if (not (= b 0)) (/ a b) a))
  (disp (new-if (not (= b 0)) (/ a b) a))

#+end_src

#+RESULTS:
: 1
: 1

The code above works as expected, because the macro does not evaluate
its arguments, and (cond) is a special form.

*** DONE Exercise 1.7 Good enough?
    CLOSED: [2019-08-22 Thu 12:52]
This exercise is a very misleading one. On the first glance is seems
that this is just about formulating a good criterion. Make no mistake,
practically solving this task means really writing all this code
carefully.

The function we are interested in is:
\begin{equation}
\label{eq:5}
f(x) = \sqrt{x}
\end{equation}

The code given in the chapter before is equivalent to the following
Newton's method formula, where $f_i$ denotes the next guess:
\begin{equation}
\label{eq:1} 
f_{i+1}_{} = \frac{f_i + \frac{x}{f_i}}{2}
\end{equation}

How on Earth does this formula even appear? Let's remember some
mathematics, namely, the Taylor series (variables unbound):
\begin{equation}
\label{eq:2}
 f(x) = f(x_{0}_{}) + f'(x_{0})(x-x_{0}) + o(x)
\end{equation}

Let us call `true' value of $\sqrt{x}=f$. Let us call our first guess
$f_{0}$. What is the value of the difference (error) between them?
Clearly, $f-f_0$. Well, the problem is — we don't know $f$. But we do
know $f^2$. Therefore $f^2-f^2_0$ is a number we know. What will be the
error on the next step of the algorithm? Let's find $f_1$ as
$f_1=f_0+\delta$. If $\delta$ is not too big, we can use the Taylor
expansion from ref:eq:1 $\delta$.
\begin{equation}
\label{eq:8}
E = f^2 - f_0^2 = f^2 - (f_0 + \delta)^2 \approx f^2 - f_0^2 - 2f_0\delta
\end{equation}


Be careful. What I expanded here is not the function value. It is the
_error_ value. Now, clearly we want our error to be as small as
possible, desirably as little as machine precision would allow. So
assuming $E=0$, we get an equation to solve:
\begin{align}
\label{eq:9}
E=0 \leftrightarrow& f^2-f_0^2-2f_0\delta=0 \\
\delta =& \frac{f_0^2 -f^2 }{2f_0}
\end{align}

Remember though that we don't need just $\delta$ here. We actually need
$f_1$. But $f_1$ is just $f_0+\delta$.
\begin{align}
\label{eq:10}
f_1 = \frac{f^2 - f_0^2}{2f_0} + f_0
\end{align}
Now if you rearrange this formula, you will get exactly the formula
ref:eq:1.

The code below is copied from SICP verbatim and implements the
algorithm above.

#+begin_src scheme :exports both :results value :session :noweb-ref simple-sqrt-iter
  (define (sqrt-iter guess x)
    (if (good-enough? guess x)
	guess
	(sqrt-iter (improve guess x) x)))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value :noweb-ref square-improve
  (define (improve guess x)
    (average guess (/ x guess)))
#+end_src

#+begin_src scheme :exports both :results value :session :noweb-ref simple-newton-recursion
  (define (good-enough? guess x)
    (< (abs (- (square guess) x)) 0.001))
  <<square-improve>>
  (define (average x y)
    (/ (+ x y) 2))
  (define (sqrt x)
    (sqrt-iter 1.0 x))

#+end_src

#+name simple-newton
#+begin_src scheme :exports both :results value :session
  <<common>>
  <<square>>
  <<simple-sqrt-iter>>
  <<simple-newton-recursion>>
  (sqrt 9)
#+end_src

#+RESULTS:
: 3.00009155413138

An example of how this fails on small numbers:

#+begin_src scheme :exports both :results value
<<simple-newton>>
(square (sqrt 0.0004))
#+end_src

#+RESULTS:
: 0.0012532224857331766

An example of why this fails on big numbers I didn't manage to
craft. Perhaps chibi-scheme has some clever way to deal with rounding?
Anyway — here is the code:
#+begin_src scheme :exports both :results value
  <<simple-newton>>
  (square (sqrt 9999999999.0))
#+end_src

#+RESULTS:
: 9999999999.0

Why exactly this is not very good algorithms is a good question. The
derivative of the square is well-defined near the 0, although the
derivative of the square root is not. Therefore, the equation ref:eq:8
become very imprecise. As we see, big number seem to be working fine
in my scheme implementation.

Let us write a better sqrt-iter?.

#+begin_src scheme :exports both :results value :noweb-ref better-sqrt-iter
  (define (sqrt-iter guess x)
   (let ((better-guess (improve guess x)))
    (if (good-enough? guess (square better-guess))
	better-guess
	(sqrt-iter better-guess x))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref better-newton
<<common>>
<<square>>
<<better-sqrt-iter>>
<<simple-newton-recursion>>
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value
<<better-newton>>
(square (sqrt 0.0004))
#+end_src

#+RESULTS:
: 0.0005452233379244715

Works faster and gives a better result. Seemingly. QED[fn:1].

*** DONE Exercise 1.8 Newton's method
    CLOSED: [2019-08-22 Thu 17:36]

This exercise is not very hard. The only difference is that the
`improve' function is not derived from a derivative of a square but
rather from a derivative of a cube.


#+name: cube-improve
#+begin_src scheme :exports both :results value
(define (cube-improve guess x)
    (/ (+ (/ x (* guess guess)) (* 2 guess)) 3))
#+end_src

#+RESULTS: cube-improve
: #<undef>

#+name: cube-good-enough
#+begin_src scheme :exports both :results value
(define (cube-good-enough? guess x)
  (< (abs (- (cube guess) x)) 0.001))
#+end_src

#+RESULTS: cube-good-enough
: #<undef>

#+name: cube-root-iter
#+begin_src scheme :exports both :results value
  (define (cube-root-iter guess x)
    (let ((better-guess (cube-improve guess x)))
      (disp better-guess)
      (if (cube-good-enough? better-guess (cube guess))
	  better-guess
	  (cube-root-iter better-guess x))))
#+end_src

#+RESULTS: cube-root-iter
: #<undef>

#+name: cube-simple
#+begin_src scheme :exports both :results output
<<common>>
<<cube>>
<<cube-improve>>
<<cube-good-enough>>
<<cube-root-iter>>
(cube-root-iter 1.0 27.0)
#+end_src

#+RESULTS: cube-simple
: 9.666666666666666
: 6.540758356453956
: 4.570876778578707
: 3.4780192333867963
: 3.0626891086275365
: 3.001274406506175
: 3.0000005410641766
: 3.0000000000000977

*** TODO Figure 1.2 Procedural decomposition of the sqrt program
TODO
*** TODO Figure 1.3 A linear recursive process for computing \(6!\).
TODO
*** TODO Figure 1.4 A linear iterative process for computing \(6!\).
TODO
*** DONE Exercise 1.9 Iterative or recursive? :macro:er_macro_transformer:chicken:
    CLOSED: [2019-08-29 Thu 15:14]

I didn't find (inc) and (dec) in my scheme, so I define them myself.

I still don't want to overload the "+" and "-" symbols, so I will call
them `plus' and `minus'.

#+name: example-substitution-first
#+begin_src scheme :exports both :results value
  (define (inc x)
    (+ 1 x))
  (define (dec x)
    (- x 1))
  (define-syntax plusF
    (er-macro-transformer
     (lambda (form rename compare?)
       (let ((a (cadr form))
	     (b (caddr form)))
n	 (if (= a 0) b `(inc (plusF ,(dec a) ,b)))))))
  (macroexpand '(plusF 4 5))
#+end_src

#+RESULTS: example-substitution-first
| inc | (inc (inc (inc 5))) |

We can see that the macro expander has expanded the computation in to
a tree of length 4. This happens because the algorithm is genuinely
recursive, the return value is not produced by a call to itself, and
therefore recursion cannot be tail-optimized. 

#+name: example-substitution-second
#+begin_src scheme :exports both :results value
  (define (inc x)
    (+ 1 x))
  (define (dec x)
    (- x 1))
  (define-syntax plusS
    (er-macro-transformer
     (lambda (form rename compare?)
       (let ((a (cadr form))
	     (b (caddr form)))
	 (if (= a 0) b `(plusS ,(dec a) ,(inc b)))))))
  (macroexpand '(plusS 4 5))
#+end_src

#+RESULTS: example-substitution-second
: 9


We can clearly see the difference. The first macro is genuinely
recursive, it expands to a series of calls, and needs to keep the
information about this calls on the stack. The second one is actually
iterative. The macro call only happens as the last step, and no
information is kept, as the return value will be just the last result,
so this macro is expanded until it's just a number.

*** DONE Exercise 1.10 Ackermann's function
    CLOSED: [2019-08-25 Sun 18:31]
Let's run the demos first:
#+name: ackerman
#+begin_src scheme :exports both :results output :session
  <<common>>
  (define (A x y)
    (cond ((= y 0.0) 0.0)
	  ((= x 0.0) (* 2.0 y))
	  ((= y 1.0) 2.0)
	  (else (A (- x 1.0) (A x (- y 1.0))))))
  (disp (A 1 10))
  (disp (A 2 4))
  (disp (A 3 3))
#+end_src

#+RESULTS: ackermann
: 1024.0
: 65536.0
: 65536.0

The values of these expressions are listed above.

#+begin_src scheme :exports both :results value :session
  (define (f n) (A 0 n))
  (define (g n) (A 1 n))
  (define (h n) (A 2 n))
  (define (k n) (* 5 n n))
#+end_src

#+RESULTS:
: #<undef>

The mathematical expressions for these formulae are:
\begin{eqnarray}
\label{eq:3}
f(n) & = & 2y\\
g(n) & = & 2^y \\
h(n) & = & 2^{2^n}\\
k(n) & = & 5n^2\\
\end{eqnarray}

Actually this is not the Ackermann's function as it is most often
defined, for example, see
[[http://mathworld.wolfram.com/AckermannFunction.html]]. But the
recurrent relation is the same. This version of the Ackermann's
function seems to be equivalent to the powers tower.

I may have lied with the coefficients, but essentially, the
Ackermann's function with parameters $n$ and $m$ works by applying the
n-the hyperoperator m times to 2. A hyperoperator is a generalization
of the standard matematical operator sequence `+', `*', `^', see
[[https://googology.wikia.org/wiki/Hyper_operator]]

*** TODO Figure 1.5 The tree-recursive process generated in computing (fib 5)
*** DONE Exercise 1.11 Recursive vs iterative
    CLOSED: [2019-08-25 Sun 19:25]

\begin{equation}
\label{eq:4}
f(n)=\left\{
\begin{array}{l@{\quad:\quad}l}
n & n<3\\
f(n-1) + 2f(n-2) + 3f(n-3) & \ge 3
\end{array}\right.
\end{equation}

#+begin_src scheme :exports both :results value :session
    (define (f-recursive n)
      (cond ((< n 3) n)
	    (else
	     (+
	      (f-recursive (- n 1))
	      (* 2 (f-recursive (- n 2)))
	      (* 3 (f-recursive (- n 3)))))))
    (f-recursive 7)
#+end_src

#+RESULTS:
: 142

#+begin_src scheme :exports both :results value :session
  (define (f-iter m n fn-1 fn-2 fn-3)
    (let ((fn (+ fn-1 (* 2 fn-2) (* 3 fn-3))))
      (cond ((= m n) fn)
	     (else (f-iter m (+ n 1) fn fn-1 fn-2)))))

  (define (f-iterative n)
    (cond ((< n 3) n)
	  (else (f-iter n 3 2 1 0))))

  (f-iterative 7)
#+end_src

#+RESULTS:
: 142

*** DONE Exercise 1.12 Recursive Pascal's triangle
    CLOSED: [2019-08-25 Sun 19:42]

\begin{tabular}{rcccccccccc}
 &    &    &    &    &  1\\\noalign{\smallskip\smallskip}
 &    &    &    &  1 &    &  1\\\noalign{\smallskip\smallskip}
 &    &    &  1 &    &  2 &    &  1\\\noalign{\smallskip\smallskip}
 &    &  1 &    &  3 &    &  3 &    &  1\\\noalign{\smallskip\smallskip}
 &  1 &    &  4 &    &  6 &    &  4 &    &  1\\\noalign{\smallskip\smallskip}
 &    &    &    &  . &  . &  . &    &    &   &   \\\noalign{\smallskip\smallskip}
\end{tabular}

#+BEGIN_SRC scheme
    (define (pascal-number line-number column-number)
      (cond ((= line-number 1) 1)
	    ((= line-number 2) 1)
	    ((= column-number 1) 1)
	    ((= column-number line-number) 1)
	    (else (+
		   (pascal-number (- line-number 1) (- column-number 1))
		   (pascal-number (- line-number 1) column-number)))))
    (pascal-number 5 3)
#+END_SRC

#+RESULTS:
: 6

*** DONE Exercise 1.13 Fibonacci
    CLOSED: [2019-08-25 Sun 23:04]

\begin{equation}
\label{eq:6}
\mbox{Fib}(n)=\left\{ 
\begin{array}{l@{\quad:\quad}l}
0 & n=0\\
1 & n=1\\
\mbox{Fib}(n-1) + \mbox{Fib}(n-2) & \mbox{otherwise}}
\end{array}\right.
\end{equation}

Abelson and Sussman define \(\varphi=(1+\sqrt{5})/2\) and \(\psi=(1-\sqrt{5})/2\).

Knowing that \( \mbox{Fib}(n) = (\varphi^{n} - \psi^n)/\sqrt{5}\) is almost all the
problem done, because \(\psi\) is clearly less than \(1\), so for large
\(n\) it will be exponentially close to \(0\), and this is where the
``closest integer'' comes from.

Let us prove the rest by induction.
\begin{eqnarray}
\label{eq:13}
\frac{\varphi^{n-1} - \psi^{n-1} + \varphi^{n-2} - \psi^{n-2}}{\sqrt{5}} &=& \frac{\varphi^{n} - \psi^{n}}{\sqrt{5}}\\
\varphi^{n-1} - \psi^{n-1} + \varphi^{n-2} - \psi^{n-2} &=& \varphi^{n} - \psi^{n} \\
(\varphi + 1)\varphi^{n-2} - (\psi + 1)\psi^{n-2} &=&  \varphi^{n} - \psi^{n}\\
(\varphi + 1 - \varphi^2)\varphi^{n-2} &=&  (\psi + 1 - \psi^2)\psi^{n-2}\\
(\frac{1+\sqrt{5}}{2} + 1 - (\frac{1+\sqrt{5}}{2})^2)\varphi^{n-2} &=&
(\frac{1-\sqrt{5}}{2} + 1 - (\frac{1-\sqrt{5}}{2}))\psi^{n-2} \\
(\frac{2+2\sqrt{5}}{4} + \frac{4}{4} - \frac{1+2\sqrt{5}+5}{4})\varphi^{n-2} &=&
(\frac{2-2\sqrt{5}}{4} + \frac{4}{4} - \frac{1-2\sqrt{5}+5}{4})\psi^{n-2}\\
0&=&0
\end{eqnarray}

This proves that the recurrent relation for \(\frac{\varphi^n-\psi^n}{\sqrt{5}}\) is the
same as for the Fibonacci sequence. Then if we prove that there exist
such \(n\) and \(n-1\) so that \(\mbox{Fib}(n) =
\frac{\varphi^n-\psi^n}{\sqrt{5}}\), then we're done.

Indeed, let's have a look at \(n=1\): \(\frac{1+\sqrt{5}}{2
\sqrt{5}} - \frac{1-\sqrt{5}}{2 \sqrt{5}} = 1\); and \(n=0\): \(
\frac{1-1}{\sqrt{5}} = 0\).

*** DONE Exercise 1.14 count-change              :macro:er_macro_transformer:
    CLOSED: [2019-08-30 Fri 16:09]

Let us use the non-standard but common er-macro-transformer to plot
the execution tree.

#+begin_src scheme :exports both :results output
  (define-syntax cc
    (er-macro-transformer
     (lambda (form rename compare?)
       (let ((amount (cadr form))
	     (kinds-of-coins (caddr form)))
	 (cond ((= amount 0) 1)
	       ((or (< amount 0) (= kinds-of-coins 0)) 0)
	       (`(+ (cc ,amount
			,(- kinds-of-coins 1))
		    (cc ,(- amount
			    (first-denomination
			     kinds-of-coins))
			,kinds-of-coins))))))))
  (define (first-denomination kinds-of-coins)
    (cond ((= kinds-of-coins 1) 1)
	  ((= kinds-of-coins 2) 5)
	  ((= kinds-of-coins 3) 10)
	  ((= kinds-of-coins 4) 25)
	  ((= kinds-of-coins 5) 50)))
(show #t " "(pretty (macroexpand '(cc 11 5))))
#+end_src

#+RESULTS:
:  (+
:   (+
:    (+
:     (+ (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 1)))))))))))
:        (+ (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 (+ 0 1)))))) (+ (+ 0 1) 0)))
:     (+ (+ (+ 0 1) 0) 0))
:    0)
:   0)

Initially I wrote the same code in Emacs Lisp, I am leaving it here
for future reference.

#+begin_src elisp :exports both :results output
    (defmacro cc (amount kinds-of-coins)
      (cond ((= amount 0) 1)
	    ((or (< amount 0) (= kinds-of-coins 0)) 0)
	    (`(+ (cc ,amount
		    ,(- kinds-of-coins 1))
		(cc ,(- amount
		       (first-denomination
			kinds-of-coins))
		    ,kinds-of-coins)))))
  (defun first-denomination (kinds-of-coins)
    (cond ((= kinds-of-coins 1) 1)
	  ((= kinds-of-coins 2) 5)
	  ((= kinds-of-coins 3) 10)
	  ((= kinds-of-coins 4) 25)
	  ((= kinds-of-coins 5) 50)))
  (pp (macroexpand-all '(cc 11 5)))

#+end_src

#+RESULTS: ?
#+begin_example
(+
 (+
  (+
   (+
    (+ 0
       (+ 0
	  (+ 0
	     (+ 0
		(+ 0
		   (+ 0
		      (+ 0
			 (+ 0
			    (+ 0
			       (+ 0
				  (+ 0 1)))))))))))
    (+
     (+ 0
	(+ 0
	   (+ 0
	      (+ 0
		 (+ 0
		    (+ 0 1))))))
     (+
      (+ 0 1)
      0)))
   (+
    (+
     (+ 0 1)
     0)
    0))
  0)
 0)
#+end_example

The space complexity of the algorithm will be dominated by the depth
of the tree — that is the value to be changed, as there is no need to
keep any additional information.

The time complexity can be estimated as follows: for every additional
value the algorithm will have to go through all passes of the
algorithm without an additional denomination, times the amount divided
by the value of an additional denomination. We can consider the
additional denomination value as a constant, and the amount of steps
for the simplest case of only one denomination is the
amount. Therefore, the algorithm is linear in amount and exponential
in the number of denominations.

\begin{equation}
\label{eq:14}
C = \Theta(n^a)
\end{equation}

*** I found a bug in ob-scheme while doing this Exercise.
 _In process I have found a bug in org-babel!_
#+begin_src scheme :exports both :results output
(display "(+ 0) ")
#+end_src

#+RESULTS:
: 0

#+begin_src scheme :exports both :results output
(display "(+ 0)")
#+end_src

#+RESULTS:
| + | 0 |

(org-babel-script-escape "(+ 0)") (org-babel-script-escape "(+ 0) ")

*** DONE Exercise 1.15 sine                      :macro:er_macro_transformer:
    CLOSED: [2019-08-30 Fri 22:34]

First let us code this thing:

Loop version:

#+begin_src scheme :exports both :results output
  (define niter 0)
  (define (cube x) (* x x x))
  (define (p x)
    (set! niter (+ niter 1))
    (- (* 3 x) (* 4 (cube x))))
  (define (sine angle)
    (if (not (> (abs angle) 0.1))
	angle
	(p (sine (/ angle 3.0)))))
  (display "sine=" )
  (display (sine 12.15))
  (display " niter=")
  (display niter)
#+end_src

#+RESULTS:
: sine=-0.39980345741334 niter=5

Let's have the macro system expand this for us.

#+begin_src scheme :exports both :results output
  (define (cube x)
    (* x x x))
  (define (p x)
    (- (* 3  x)
       (* 4 (cube x))))
  (define-syntax sine
    (er-macro-transformer
     (lambda (form rename compare?)
       (let ((a (cadr form)))
	 (if (< (abs a) 0.1)
	     a
	     `(p (sine ,(/ a 3))))))))
  (show #t " " (pretty (macroexpand '(sine 12.15))))

#+end_src

#+RESULTS:
:  (p (p (p (p (p 0.05)))))

Theoretically, we can expand everything at once. 

#+begin_src scheme :exports both :results output
  (define-syntax cube
    (er-macro-transformer
     (lambda (form rename compare?)
       (let ((x (cadr form)))
	 `(* ,x ,x ,x)))))
  (define-syntax p
    (er-macro-transformer
     (lambda (form rename compare?)
       (let ((x (cadr form)))
	 `(- (* 3 ,x)
	     (* 4 (cube ,x)))))))
  (define-syntax sine
    (er-macro-transformer
     (lambda (form rename compare?)
       (let ((a (cadr form)))
	 (if (< (abs a) 0.1)
	     a
	     `(p (sine ,(/ a 3))))))))
  (show #t " " (pretty (macroexpand '(sine 12.15))))
#+end_src

#+RESULTS:
#+begin_example
 (-
  (* 3
     (-
      (* 3
         (-
          (* 3
             (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                (* 4
                   (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                      (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                      (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
          (* 4
             (*
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))))))
      (* 4
         (*
          (-
           (* 3
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
           (* 4
              (*
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))
          (-
           (* 3
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
           (* 4
              (*
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))
          (-
           (* 3
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
           (* 4
              (*
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))))))
  (* 4
     (*
      (-
       (* 3
          (-
           (* 3
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
           (* 4
              (*
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))))))
       (* 4
          (*
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))))))))
      (-
       (* 3
          (-
           (* 3
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
           (* 4
              (*
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))))))
       (* 4
          (*
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))))))))
      (-
       (* 3
          (-
           (* 3
              (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                 (* 4
                    (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                       (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
           (* 4
              (*
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))))))
       (* 4
          (*
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))
           (-
            (* 3
               (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                  (* 4
                     (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                        (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))
            (* 4
               (*
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))))
                (- (* 3 (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05))))
                   (* 4
                      (* (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))
                         (- (* 3 0.05) (* 4 (* 0.05 0.05 0.05)))))))))))))))
#+end_example

As seen from the code above, the amount of steps is 5. It is easily
seen from the fact that the application of ~p~ starts when *x* is
sufficiently small, and that requires \(0.1 > 12.15\cdot(\frac{1}{3})^n \Rightarrow n
= O(\log_3 121.5)\) steps.

~(sine x)~ is expandable in constant space and time, ~(cube x)~ is
expandable in constant space and time if multiplication is an
elementary operation. Therefore the only operation left is
~p~. Therefore, time and space are of equal order of magnitude.

 - \(\left\lceil \log_3 121.5 \right\rceil = 5\)
 - \(O(\ln(a\cdot b))\) where \(a\) is the angle and \(b\) is precision

*** DONE Exercise 1.16 Iterative exponentiation
    CLOSED: [2019-08-30 Fri 23:20]

For the start, let's input the code.

#+begin_src scheme :exports both :results value
  (define (expt b n)
    (if (= n 0)
	1
	(* b (expt b (- n 1)))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value
  (define (expt b n)
    (expt-iter b n 1))
  (define (expt-iter b counter product)
    (if (= counter 0)
	product
	(expt-iter b
		   (- counter 1)
		   (* b counter product))))
#+end_src

#+begin_src scheme :exports both :results value
  (define (fast-expt b n)
    (cond ((= n 0) 1)
	  ((even? n) (square (fast-expt b (/ n 2))))
	  (else (* b (fast-expt b (- n 1))))))
  (define (even? n)
    (= (remainder n 2) 0))
  (fast-expt 2 10)
#+end_src

#+RESULTS:
: 1024

#+begin_src scheme :exports both :results value
    (define (fast-expt b n a)
      (cond ((= n 0) a)
	    ((even? n)  (fast-expt (square b) (/ n 2) a))
	    (else (fast-expt b (- n 1) (* a b)))))
    (define (even? n)
      (= (remainder n 2) 0))
    (define (faster-expt b n)
      (fast-expt b n 1))
    (faster-expt 2 10)
#+end_src

#+RESULTS:
: 1024

The answer is the code block above. We just collect some data and put
it into the state variable *a*.

*** DONE Exercise 1.17 Fast multiplication
    CLOSED: [2019-08-30 Fri 23:48]
#+begin_src scheme :exports both :results value
  (define (double a)
    (* 2 a))
  (define (halve a)
    (if (even? a)
	(/ a 2)
	(raise "Error: a not even.")))
  (define (even? n)
	(= (remainder n 2) 0))
  (define (* a b)
    (cond 
     ((= b 0) 0)
     ((even? b) (double (* a (halve b))))
     (else (+ a (* a (- b 1))))))
  (* 137 17)
#+end_src

#+RESULTS:
: 2329

The procedure above uses logarithmic time and space, because for every
subtraction there is also at least one division, so the total
convergence speed is exponential. This could be reformulated as an
iterative procedure, with an accumulator variable, but I am too lazy.

*** DONE Exercise 1.18 Iterative multiplication
    CLOSED: [2019-08-31 Sat 11:43]

In Exercise 1.17 I said that I was too lazy to design an iterative
procedure. Well, now I do it in this exercise.

#+begin_src scheme :exports both :results value
  (define (double a)
    (* 2 a))
  (define (halve a)
    (if (even? a)
	(/ a 2)
	(raise "Error: a not even.")))
  (define (even? n)
	(= (remainder n 2) 0))
  (define (mul a b accumulator)
    (cond 
     ((= b 0) accumulator)
     ((even? b) (mul (double a) (halve b)))
     (else (mul a (- b 1) (+ a accumulator)))))
  (* 137 17)
#+end_src

#+RESULTS:
: 2329

The idea here is exactly the same as in the previous Exercise 1.18.

*** DONE Exercise 1.19 Logarithmic Fibonacci
    CLOSED: [2019-09-01 Sun 20:42]

As usualy, let's first copy the code of ~fib-iter~.

#+begin_src scheme :exports both :results value
  (define (fib n)
    (fib-iter 1 0 n))
  (define (fib-iter a b count)
    (if (= count 0)
	b
	(fib-iter (+ a b) a (- count 1))))
  (fib 10)
#+end_src

#+RESULTS:
: 55

The formula for \(T\) is the following:

\begin{eqnarray}
T_{pq} \begin{pmatrix} a\\ b \end{pmatrix} & = & \begin{pmatrix} aq+bq+ap \\ bp + aq \end{pmatrix} &\\ 
T_{pq} \left( T_{pq} \begin{pmatrix} a\\ b \end{pmatrix} \right) & = & \begin{pmatrix} (aq+bq+ap)q+(bp + aq)q+(aq+bq+ap)p \\ (bp + aq)p + (aq+bq+ap)q \end{pmatrix} &\\
T_{p'q'}\begin{pmatrix} a\\ b \end{pmatrix} & = & \begin{pmatrix}a(2pq + qq) + a(pp+qq) + b(2pq + qq)\\ a(2pq + qq) + b(pp + qq) \end{pmatrix}& \\
\end{eqnarray}
From here we can easily see the values for \(p\prime\) and \(q'\):
# \(a(2pq + qq) + a(pp+qq) + b(2pq + qq)\)
# \(a(2pq + qq) + b(pp + qq)\)

\(p'=pp+qq\), \(q' = 2pq+qq\)

Let us substitute them into the code given by Abelson and Sussman.

#+begin_src scheme :exports both :results value
  (define (fib n)
    (fib-iter 1 0 0 1 n))
  (define (fib-iter a b p q count)
    (cond ((= count 0) b)
	  ((even? count)
	   (fib-iter a
		     b
		     (+ (* p p) (* q q))
		     (+ (* 2 p q) (* q q))
		     (/ count 2)))
	  (else (fib-iter (+ (* b q) (* a q) (* a p))
			  (+ (* b p) (* a q))
			  p
			  q
			  (- count 1)))))
  (fib 10)
#+end_src

#+RESULTS:
: 55

Works.

*** *Interjection* ir-macro-transformer.

#+begin_src scheme :exports both :results value
  (define-syntax swap!
    (ir-macro-transformer
     (lambda (form inject compare?)
       (let ((a (cadr form))
	     (b (caddr form))
	     (tmp (cadr form)))
	     (set! a b)
	     (set! b tmp)))))
  (define x 4)
  (define y 5)
  (swap! x y)
  (list x y)
#+end_src

#+RESULTS:
: "{Exception #19 user \"undefined variable\" (ir-macro-transformer) #<procedure #f> (#f . 3)}"

*** DONE Exercise 1.20 GCD applicative vs normal :er_macro_transformer:macro:
    CLOSED: [2019-09-01 Sun 23:04]
The exercise urges us to recall the difference between the normal
order and the applicative order of evaluation.

 *Normal*: fully expand the computation tree until obtained an
expression involving only primitive operators.

 *Applicative*: evaluate the arguments and then apply.

First let us print the execution tree of the normal order.
#+begin_src scheme :exports both :results output
    (define-syntax gcd-normal
      (er-macro-transformer
       (lambda (form rename compare?)
	 (let ((a (cadr form))
	       (b (caddr form)))
	   (if (= b 0)
		`(if (= ,b 0)
                     ,a
                     (remainder ,a ,b))
		`(if (= ,b 0)
		     (,a (remainder ,a ,b))
		     (gcd-normal ,b ,(remainder a b))))))))
      (display (show #f " " (pretty (macroexpand '(gcd-normal 206 40)))))
#+end_src

#+RESULTS:
:  (if (= 40 0)
:      (206 (remainder 206 40))
:      (if (= 6 0)
:          (40 (remainder 40 6))
:          (if (= 4 0)
:              (6 (remainder 6 4))
:              (if (= 2 0) (4 (remainder 4 2)) (if (= 0 0) 2 (remainder 2 0))))))

Now let us show the applicative order.
#+begin_src scheme :exports both :results output
    (define-syntax gcd-normal
      (er-macro-transformer
       (lambda (form rename compare?)
	 (let ((a (cadr form))
	       (b (caddr form)))
	   (if (= b 0)
		`(if (= ,b 0)
                     ,a
                     'division-by-zero)
		`(if (= ,b 0)
		     (,a (remainder ,a ,b))
		     (gcd-normal ,b ,(remainder a b))))))))
      (display (show #f " " (pretty (macroexpand '(gcd-normal 206 40)))))
#+end_src

#+RESULTS:
:  (if (= 40 0)
:      (206 (remainder 206 40))
:      (if
:       (= 6 0)
:       (40 (remainder 40 6))
:       (if (= 4 0)
:           (6 (remainder 6 4))
:           (if (= 2 0) (4 (remainder 4 2)) (if (= 0 0) 2 'division-by-zero)))))

The problem here would arise, if the ~(if)~ form had a normal
evaluation order, because the last division, ~(remainder 2 0)~ may be
a forbidden operation, involving a division by zero. On the other
hand, the evaluation of ~(remainder x 0)~ could be defined as *x*, and
then the algorithm would evaluate one more (useless) remainder.

*** DONE Exercise 1.21 smallest-divisor
    CLOSED: [2019-09-01 Sun 23:43]

As usual, let us first copy the code for the ~smallest-divisor~.

#+begin_src scheme :exports both :results output :noweb-ref primetest
  (define (smallest-divisor n)
    (find-divisor n 2))
  (define (find-divisor n test-divisor)
    (cond ((> (square test-divisor) n) n)
	  ((divides? test-divisor n) test-divisor)
	  (else (find-divisor n (+ test-divisor 1)))))
  (define (divides? a b) (= (remainder b a) 0))

  (define (prime? n)
    (= n (smallest-divisor n)))
#+end_src

#+begin_src scheme :exports both :results output
  <<primetest>>
  (display (smallest-divisor 199))
  (newline)
  (display (smallest-divisor 1999))
  (newline)
  (display (smallest-divisor 19999))
  (newline)
  (display (/ 19999 7))
  (newline)
#+end_src

#+RESULTS:
: 199
: 1999
: 7
: 2857

Well, this problem doesn't look too complicated on the first glance.

*** DONE Exercise 1.22 timed-prime-test
    CLOSED: [2019-09-02 Mon 00:44]

#+begin_src scheme :exports both :results output :noweb-ref timed-primetest
  (define (runtime) (* 1000 (current-second)))

  (define (timed-prime-test n)
    (newline)
    (display n)
    (start-prime-test n (runtime)))

  (define (start-prime-test n start-time)
    (if (prime? n)
	(report-prime (- (runtime) start-time))))

  (define (report-prime elapsed-time)
    (display " *** ")
    (display elapsed-time))
  (define (search-for-primes start finish)
    (timed-prime-test start)
    (if (< (+ 1 start) finish)
	(if (even? start)
	    (search-for-primes (+ start 1) finish)
	    (search-for-primes (+ start 2) finish))))
#+end_src

#+begin_src scheme :exports both :results output
  <<primetest>>
  <<timed-primetest>>
  (search-for-primes 1000 1020)
  (newline)
  (search-for-primes 10000 10038)
  (newline)
  (search-for-primes 100000 100044)
  (newline)
  (search-for-primes 1000000 1000038)
#+end_src

#+RESULTS:
#+begin_example

1000
1001
1003
1005
1007
1009 *** 0.006103515625
1011
1013 *** 0.005859375
1015
1017
1019 *** 0.005859375

10000
10001
10003
10005
10007 *** 0.016845703125
10009 *** 0.016845703125
10011
10013
10015
10017
10019
10021
10023
10025
10027
10029
10031
10033
10035
10037 *** 0.016845703125

100000
100001
100003 *** 0.052978515625
100005
100007
100009
100011
100013
100015
100017
100019 *** 0.052978515625
100021
100023
100025
100027
100029
100031
100033
100035
100037
100039
100041
100043 *** 0.052001953125

1000000
1000001
1000003 *** 0.163818359375
1000005
1000007
1000009
1000011
1000013
1000015
1000017
1000019
1000021
1000023
1000025
1000027
1000029
1000031
1000033 *** 0.1650390625
1000035
1000037 *** 0.1640625
#+end_example

 - Write the procedure: done.
 - Find the smallest three primes greater than 1000   : found.
 - Find the smallest three primes greater than 10000  : found.
 - Find the smallest three primes greater than 100000 : found.
 - Find the smallest three primes greater than 1000000: found.
 - The timing data confirms the prediction. \(\sqrt{10}\approx3\), \(0.16 \approx 3\cdot1.05\).
 - The execution time per step for testing 1.000.000 is 1.63e-07. The
   execution time per step for testing 100.000 5.3199e-07. At least on
   my machine the claim doesn't seem to hold very well.

*** DONE Exercise 1.23 (next test-divisor)
    CLOSED: [2019-09-02 Mon 09:56]

#+begin_src scheme :exports both :results value :noweb-ref improved-primetest
  (define (next x)
    (if (= 2 x)
	3
	(+ x 2)))
  (define (smallest-divisor n)
    (find-divisor n 2))
  (define (find-divisor n test-divisor)
    (cond ((> (square test-divisor) n) n)
	  ((divides? test-divisor n) test-divisor)
	  (else (find-divisor n (next test-divisor)))))
  (define (divides? a b) (= (remainder b a) 0))

  (define (prime? n)
    (= n (smallest-divisor n)))

#+end_src

#+begin_src scheme :exports both :results output
<<improved-primetest>>
<<timed-primetest>>
(timed-prime-test 1009)
(timed-prime-test 1013)
(timed-prime-test 1019)
(timed-prime-test 10007)
(timed-prime-test 10009)
(timed-prime-test 10037)
(timed-prime-test 100003)
(timed-prime-test 100019)
(timed-prime-test 100043)
(timed-prime-test 1000003)
(timed-prime-test 1000033)
(timed-prime-test 1000037)

#+end_src

#+RESULTS:
#+begin_example

1009 *** 0.010009765625
1013 *** 0.00390625
1019 *** 0.00390625
10007 *** 0.010009765625
10009 *** 0.010009765625
10037 *** 0.010009765625
100003 *** 0.031005859375
100019 *** 0.03076171875
100043 *** 0.030029296875
1000003 *** 0.10205078125
1000033 *** 0.104736328125
1000037 *** 0.10205078125
#+end_example

We can see that the test does show a speed improvement, although not
as impressive as 2 times. We can observe that the number of steps is
not really halved, since ~(+ a b)~ requires one operation, and ~(if (=
2 x) 3 else (+ 3 2))~ requires three operations, so the speed should
improve by 3/2, which we can observe.

*** DONE Exercise 1.24 Fermat method
    CLOSED: [2019-09-02 Mon 11:32]

Firstly we need the ~(fast-prime?)~ procedure.

#+begin_src scheme :exports both :results value :noweb-ref random
(define (random x)
  (random-integer x))
#+end_src

#+RESULTS:
: 30

#+begin_src scheme :exports both :results value :noweb-ref expmod
  (define (expmod base exp m)
    (cond ((= exp 0) 1)
	  ((even? exp)
	   (remainder
	    (square (expmod base (/ exp 2) m))
	    m))
	  (else
	   (remainder
	    (* base (expmod base (- exp 1) m))
	    m))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref fermat-primetest
<<random>>
  (define (fermat-test n)
    (define (try-it a)
      (= (expmod a n n) a))
    (try-it (+ 1 (random (- n 1)))))
  (define prime-test fermat-test)
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref fast-prime
  (define (fast-prime? n times)
    (cond ((= times 0) true)
	  ((prime-test n) (fast-prime? n (- times 1)))
	  (else false)))
  (define true #t)
  (define false #f)
  (define (prime? x)
    (fast-prime? x 10))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<expmod>>
<<fermat-primetest>>
<<fast-prime>>
<<timed-primetest>>
(timed-prime-test 1009)
(timed-prime-test 1013)
(timed-prime-test 1019)
(timed-prime-test 10007)
(timed-prime-test 10009)
(timed-prime-test 10037)
(timed-prime-test 100003)
(timed-prime-test 100019)
(timed-prime-test 100043)
(timed-prime-test 1000003)
(timed-prime-test 1000033)
(timed-prime-test 1000037)
(timed-prime-test 1000)
(timed-prime-test 6601)
#+end_src

#+RESULTS:
#+begin_example

1009 *** 0.0830078125
1013 *** 0.057861328125
1019 *** 0.060791015625
10007 *** 0.072998046875
10009 *** 0.071044921875
10037 *** 0.07275390625
100003 *** 0.083251953125
100019 *** 0.0849609375
100043 *** 0.085693359375
1000003 *** 0.09521484375
1000033 *** 0.09619140625
1000037 *** 0.09814453125
1000
6601 *** 0.0478515625
#+end_example

Firstly, observe that the interpreter seems to be doing some black magic, so
that the test for 1009 takes more time than the test for 1013.

Secondly, observe that indeed, the speed seems to have reduced its dependence
on the length of a number, and if we want to test even bigger numbers, the
dependency should become even smaller, as \(\log(n)\) grows very slowly. In
particular, comparing the range around 1000 and 1000.000, the ratio of
\(\frac{\log_{10}(1000000)}{\log_{10}(1000)} = \frac{6}{3} = 2\). This doesn't seem
to be completely the case, but hey, there may be some constants involved, as
well as some interpreter dark magic.

*** DONE Exercise 1.25 expmod
    CLOSED: [2019-09-02 Mon 12:46]

Well, in principle, Alyssa's algorithm should work. The problem here really
is that we would have to store the number \(a^n\), which is a very big number,
especially because we are interested in testing primality of very large
numbers (e.g., 512-bit long cryptography keys), and \((2^{256-1})^{2^{256}}\)
is a very large number.

*** DONE Exercise 1.26 square vs mul
    CLOSED: [2019-09-02 Mon 12:50]

The hint here lies in the name of the person helping Louis. Eva Lu Ator
sounds similar to "evaluator", and the reason for Louis's problem really lies
in the optimization capabilities of the interpreter. That is, if the
evaluating algorithm uses applicative order, then the ~expmod~ is evaluated
twice per step, which makes ~(/ exp 2)~ useless. If, however, the interpreter
can memoize the results, his algorithm would be just as good.

*** DONE Exercise 1.27 Carmichael numbers
    CLOSED: [2019-09-02 Mon 20:50]

First let us recall some Carmichael numbers.

| # |      |
|---+------|
| 1 |  561 |
| 2 | 1105 |
| 3 | 1729 |
| 4 | 2465 |
| 5 | 2821 |
| 6 | 6601 |

We already have a procedure that computes \(a^n\mod n\), and a procedure that
computes \(a\mod n\) is even a scheme primitive. Moreover, we even have all
the code that does the comparison, with the single difference - our existing
code takes an initial guess uniformly at random, whereas we need to check all
\( a < n\).

#+begin_src scheme :exports both :results output
<<expmod>>
  (define (congruent? a n)
    (= (expmod a n n) a))
  (define (carmichael-iter a n)
    (cond ((= a n) #t)
	  ((not (congruent? a n)) #f)
	  (else (carmichael-iter (+ 1 a) n))))
  (define (carmichael-or-prime? n)
    (carmichael-iter 1 n))
  (define (test-carmichael n)
    (display "Testing ")
    (display n)
    (display ": ")
    (if (carmichael-or-prime? n)
      (display "true")
      (display "false"))
    (newline))
  (test-carmichael 561)
  (test-carmichael 1105)
  (test-carmichael 1729)
  (test-carmichael 2465)
  (test-carmichael 2821)
  (test-carmichael 6601)
  (test-carmichael 20)
  (test-carmichael 7)
#+end_src

#+RESULTS:
: Testing 561: true
: Testing 1105: true
: Testing 1729: true
: Testing 2465: true
: Testing 2821: true
: Testing 6601: true
: Testing 20: false
: Testing 7: true

*** DONE Exercise 1.28 Miller-Rabin
    CLOSED: [2019-09-02 Mon 23:28]
#+begin_src scheme :exports both :results value :noweb-ref expmod-miller-rabin
  (define (expmod base exp m)
    (cond ((= exp 0) 1)
	  ((even? exp)
	   (let* ((root (expmod base (/ exp 2) m))
		  (sq (square root)))
	     (if (and (= (remainder sq m) 1) (not (or (= root 1) (= root (- m 1)))))
	      0
	      (remainder sq m))))
	  (else
	   (remainder
	    (* base (expmod base (- exp 1) m))
	    m))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value :noweb-ref miller-rabin-primetest
    <<random>>
      (define (rabin-test n)
	(define (try-it a)
	  (let ((result (expmod a (- n 1) n) ))
	    (if (or (= 1 result)  (= n 1) (= n 0))
	    #t
	    #f)))
	(if (not (= n 1)) (try-it (+ 1 (random (- n 1)))) #t))
      (define prime-test rabin-test)

#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output :noweb-ref rabin-prime
<<expmod-miller-rabin>>
<<miller-rabin-primetest>>
<<fast-prime>>
<<timed-primetest>>
#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
<<rabin-prime>>
(timed-prime-test 1009)
(timed-prime-test 1013)
(timed-prime-test 1019)
(timed-prime-test 10007)
(timed-prime-test 10009)
(timed-prime-test 10037)
(timed-prime-test 100003)
(timed-prime-test 100019)
(timed-prime-test 100043)
(timed-prime-test 1000003)
(timed-prime-test 1000033)
(timed-prime-test 1000037)
(timed-prime-test 1000)
(timed-prime-test 6601)

#+end_src

#+RESULTS:
#+begin_example

1009 *** 0.09716796875
1013 *** 0.086669921875
1019 *** 0.087158203125
10007 *** 0.1220703125
10009 *** 0.113037109375
10037 *** 0.113037109375
100003 *** 0.130859375
100019 *** 0.133056640625
100043 *** 0.132080078125
1000003 *** 0.151123046875
1000033 *** 0.172119140625
1000037 *** 0.156982421875
1000
6601
#+end_example

I used the ~(let)~ construction introduced in the later chapters, because I
find bindings with nested procedures confusing.

*** DONE Exercise 1.29 Simpson's integral
    CLOSED: [2019-09-03 Tue 10:36]

Since at the end of the task we are told to compare the result of our
algorithm with the results of the ~integral~ procedure, let us first copy the
integral code.

#+begin_src scheme :exports both :results value :noweb-ref integral-common
  (define (sum term a next b)
    (if (> a b)
	0
	(+ (term a)
	   (sum term (next a) next b))))
  (define (cube x)
    (* x x x))
  (define (next point)
    (+ point 1))
#+end_src

#+begin_src scheme :exports both :results value 
<<integral-common>>
  (define (integral f a b dx)
    (define (add-dx x)
      (+ x dx))
    (* (sum f (+ a (/ dx 2.0)) add-dx b)
       dx))
  (list (integral cube 0 1 0.01) (integral cube 0 1 0.001))

#+end_src

#+RESULTS:
| 0.24998750000000053 | 0.24999987500000106 |

#+begin_src scheme :exports both :results output
  <<integral-common>>
  (define (integral-simpson f a b npoints)
    (define h (/ (- b a) npoints))
    (define h/3 (/ h 3))
    (define (f_k k)
      (* (f (+ a (* k h))) (cond ((= k 0) 1)
				 ((= k npoints) 1)
				 ((odd? k) 4)
				 ((even? k) 2))))
    (* h/3 (sum f_k 0 next npoints)))
  (display (integral-simpson cube 0 1 100))
  (newline)
  (display (integral-simpson cube 0 1 1000))
#+end_src

#+RESULTS:
: 1/4
: 1/4

An impressive result. I don't know at which point of the computation the
interpreter switches to an exact representation, but meh, this result is good.

*** DONE Exercise 1.30 Iterative sum
    CLOSED: [2019-09-03 Tue 11:19]

#+begin_src scheme :exports both :results output
  (define (inc x) (+ x 1))
  (define (identity x) x)
  (define (sum term a next b)
    (define (iter a result)
      (if (= a b)
	  (+ a result)
	  (iter (next a) (+ a result))))
    (iter a 0))

  (sum identity 1 inc 10)

#+end_src

#+RESULTS:
: 55

*** DONE Exercise 1.31 Product
    CLOSED: [2019-09-03 Tue 11:59]
**** DONE a. Defining product
     CLOSED: [2019-09-03 Tue 11:56]
 #+begin_src scheme :exports both :results value
   (define (inc x) (+ x 1))
   (define (identity x) x)
   (define (product term a next b)
     (define (iter a result)
       (if (= a b)
	   (* (term a) result)
	   (iter (next a) (* (term a) result))))
     (iter a 1.0))
   (define (factorial x) (product identity 1 inc 6))
   (factorial 6)
   (define (pi precision)
     (define (enumerator index)
       (cond ((odd?  index) (+ index 1.0))
	     ((even? index) (+ index 2.0))
	     (else (error "Error"))))
     (define (denominator index)
       (cond ((odd?  index) (+ index 2.0))
	     ((even? index) (+ index 1.0))
	     (else (error "Error"))))
     (define (fraction index)
       (/ (enumerator index) (denominator index)))
     (* 4.0 (product fraction 1 inc precision)))
     (pi 1280)
 #+end_src

 #+RESULTS:
 : 3.142818162579486

I can say that it converges very-very slowly.
**** DONE b. A recursive version
     CLOSED: [2019-09-03 Tue 11:59]

#+begin_src scheme :exports both :results value
   (define (inc x) (+ x 1))
   (define (identity x) x)
   (define (product term a next b)
     (define (iter a result)
       (if (= a b)
	   (* (term a) result)
	   (* (iter (next a) (term a)) result)))
     (iter a 1.0))
   (define (factorial x) (product identity 1 inc 6))
   (factorial 6)
#+end_src

#+RESULTS:
: 720.0

Doesn't make too much sense to me, but here you are.

*** DONE Exercise 1.32 Accumulator
    CLOSED: [2019-09-03 Tue 12:23]
I will cheat a little bit in this exercise, I will run ~sum~ as an iterative
procedure and ~product~ as a recursive procedure, so at the end I will have
two implementations, not 4, but that should not be too much of a digression.
#+begin_src scheme :exports both :results value :noweb-ref accumulator-common
   (define (inc x) (+ x 1))
   (define (identity x) x)
#+end_src

**** DONE Implement ~sum~ in terms of an iterative accumulator
     CLOSED: [2019-09-03 Tue 12:23]
#+begin_src scheme :exports both :results value
<<accumulator-common>>
  (define (accumulate combiner null-value term a next b)
       (define (iter a result)
	 (if (>= a b)
	     (combiner (term a) result)
	     (combiner (iter (next a) (term a)) result)))
       (iter a null-value))
  (define (sum term a next b)
    (accumulate + 0 term a next b))
  (sum identity 1 inc 10)
#+end_src

#+RESULTS:
: 55

**** DONE Implement ~product~ in terms of a recursive process
     CLOSED: [2019-09-03 Tue 12:22]

#+begin_src scheme :exports both :results value
<<accumulator-common>>
  (define (accumulate combiner null-value term a next b)
       (define (iter a result)
	 (if (= a b)
	     (combiner (term a) result)
	      (iter (next a) (combiner (term a) result) )))
       (iter a null-value))
  (define (product term a next b)
    (accumulate * 1 term a next b))
  (product identity 1 inc 10)

#+end_src

#+RESULTS:
: 3628800

*** DONE Exercise 1.33 filtered-accumulate
    CLOSED: [2019-09-03 Tue 14:36]
**** DONE a. Sum-of-squares-of-primes
    CLOSED: [2019-09-03 Tue 14:24]
#+begin_src scheme :exports both :results value :noweb-ref filtered-accumulate
  <<accumulator-common>>
  <<rabin-prime>>
    (define (filtered-accumulate combiner filter null-value term a next b)
     (define (iter a result)
       (if (= a b)
	   (combiner (if (filter a) (term a) null-value) result)
	   (iter (next a) (combiner (if (filter a) (term a) null-value) result))))
     (iter a null-value))
     #+end_src
     
#+begin_src scheme :exports both :results value 
    <<filtered-accumulate>>
    (define (sum-square-prime a next b)
      (filtered-accumulate + prime? 0 square a next b))
    (sum-square-prime 1 inc 10)
#+end_src

#+RESULTS:
: 88
**** DONE b. Product of positive integers mutually prime with n
     CLOSED: [2019-09-03 Tue 14:36]

#+begin_src scheme :exports both :results output
  <<filtered-accumulate>>
  (define (product-mutually-prime n)
    (define (filter-gcd x)
      (if (= (gcd n x) 1)
	  #t
	  #f))
    (filtered-accumulate * filter-gcd 1 identity 1 inc n))
  (display (product-mutually-prime 10))
#+end_src

#+RESULTS:
: 189

Here I used the ~gcd~ function from the standard library.

*** DONE Exercise 1.34 lambda
    CLOSED: [2019-09-03 Tue 14:44]

#+begin_src scheme :exports both :results value :noweb-ref example-lambda
(define (f g) (g 2))
#+end_src

#+begin_src scheme :exports both :results value
<<example-lambda>>
(define (square x) (* x x))
(f square)
#+end_src

#+RESULTS:
: 4

#+begin_src scheme :exports both :results value
<<example-lambda>>
(f (lambda (z) (* z (+ z 1))))
#+end_src

#+RESULTS:
: 6

#+begin_src scheme :exports both :results value
<<example-lambda>>
(f f)
#+end_src

#+RESULTS:
: "{Exception #19 user \"non procedure application\" (2) #<procedure #f> (\"/usr/lib64/chibi/init-7.scm\" . 230)}"

Well, no wonder. The final combination reduces to ~(2 2)~, which *IS* a
non-procedure application.

*** DONE Exercise 1.35 fixed-point
    CLOSED: [2019-09-03 Tue 21:05]



\(\varphi = \frac{1+\sqrt{5}}{2}\)
\(x\mapsto 1+\frac{1}{x}\)
Let's substitute:
\( \frac{1+\sqrt{5}}{2} &=& 1+ \frac{2}{1+\sqrt{5}} \)
\( (1+\sqrt{5})^2 = 2(1+\sqrt{5})+ 4\)
\( 1 + 2 \sqrt{5} + 5 = 2 + 2 \sqrt{5} + 4 \)
\(6 = 6\)


#+begin_src scheme :exports both :results value :noweb-ref fixed-point-silent
  (define tolerance 0.00001)
  (define (fixed-point f first-guess)
    (define (close-enough? v1 v2)
      (< (abs (- v1 v2))
	 tolerance))
    (define (try guess)
      (let ((next (f guess)))
	(if (close-enough? guess next)
	    next
	    (try next))))
  (try first-guess))
#+end_src

#+begin_src scheme :exports both :results value
<<fixed-point-silent>>
(fixed-point cos 1.0)
#+end_src

#+RESULTS:
: 0.7390822985224024

#+begin_src scheme :exports both :results value
  <<fixed-point-silent>>
  (define (golden-transform x)
    (+ 1 (/ 1 x)))
  (fixed-point golden-transform 1.0)

#+end_src

#+RESULTS:
: 1.6180327868852458

#+begin_src scheme :exports both :results value
(/ (+ 1 (sqrt 5)) 2)
#+end_src

#+RESULTS:
: 1.618033988749895

The difference is not too big.

*** DONE Exercise 1.36 fixed-point-with-dampening
    CLOSED: [2019-09-03 Tue 21:55]

#+begin_src scheme :exports both :results value :noweb-ref fixed-point-verbose
  (define tolerance 0.00001)
  (define (fixed-point f first-guess)
    (define (close-enough? v1 v2)
      (display "Guesses: ")
      (display v1)
      (display " ")
      (display v2)
      (newline)
      (< (abs (- v1 v2))
	 tolerance))
    (define (try guess)
      (let ((next (f guess)))
	(if (close-enough? guess next)
	    next
	    (try next))))
  (try first-guess))
#+end_src

To find a solution to \(x^x=1000\), let us rearrange: \( x = \log_x1000 =
\frac{\log 1000}{\log x}\).

#+begin_src scheme :exports both :results value :noweb-ref log1000
(define (log1000/logx x)
  (/ (log 1000) (log x)))
#+end_src

#+begin_src scheme :exports both :results output
<<fixed-point-verbose>>
<<log1000>>
(display (fixed-point log1000/logx 5))
#+end_src

#+RESULTS:
#+begin_example
Guesses: 5 4.29202967422018
Guesses: 4.29202967422018 4.741863119908242
Guesses: 4.741863119908242 4.438204569837609
Guesses: 4.438204569837609 4.635299887107611
Guesses: 4.635299887107611 4.50397811613643
Guesses: 4.50397811613643 4.589989462723705
Guesses: 4.589989462723705 4.53301150767844
Guesses: 4.53301150767844 4.570475672855484
Guesses: 4.570475672855484 4.545720389670642
Guesses: 4.545720389670642 4.562024936588171
Guesses: 4.562024936588171 4.551263234080531
Guesses: 4.551263234080531 4.55835638768598
Guesses: 4.55835638768598 4.553676852183342
Guesses: 4.553676852183342 4.55676216434628
Guesses: 4.55676216434628 4.554727130670954
Guesses: 4.554727130670954 4.556069054770006
Guesses: 4.556069054770006 4.555184018843625
Guesses: 4.555184018843625 4.5557676565438205
Guesses: 4.5557676565438205 4.555382746639082
Guesses: 4.555382746639082 4.55563658243586
Guesses: 4.55563658243586 4.555469180245326
Guesses: 4.555469180245326 4.555579577901
Guesses: 4.555579577901 4.5555067722873686
Guesses: 4.5555067722873686 4.5555547860484085
Guesses: 4.5555547860484085 4.555523121789556
Guesses: 4.555523121789556 4.555544003742869
Guesses: 4.555544003742869 4.555530232469306
Guesses: 4.555530232469306 4.555539314360711
4.555539314360711
#+end_example

#+begin_src scheme :exports both :results value :noweb-ref fixed-point-verbose-with-dampening
  (define tolerance 0.00001)
  (define (fixed-point f first-guess)
    (define (close-enough? v1 v2)
      (display "Guesses: ")
      (display v1)
      (display " ")
      (display v2)
      (newline)
      (< (abs (- v1 v2))
	 tolerance))
    (define (try guess)
      (let ((next (f guess)))
	(if (close-enough? guess next)
	    next
	    (try (/ (+ guess next) 2)))))
  (try first-guess))
#+end_src

#+begin_src scheme :exports both :results output
<<fixed-point-verbose-with-dampening>>
<<log1000>>
(display (fixed-point log1000/logx 5))
#+end_src

#+RESULTS:
: Guesses: 5 4.29202967422018
: Guesses: 4.64601483711009 4.49720773504196
: Guesses: 4.571611286076025 4.544977348996107
: Guesses: 4.558294317536066 4.553717728226165
: Guesses: 4.556006022881116 4.555225576581478
: Guesses: 4.555615799731297 4.555482885419889
: Guesses: 4.555549342575593 4.555526711628406
: Guesses: 4.555538027102 4.555534173941779
: 4.555534173941779

Well, the amount of steps is visibly smaller. Works.

*** DONE Exercise 1.37 cont-frac
    CLOSED: [2019-09-04 Wed 10:34]
**** DONE a. recursive
     CLOSED: [2019-09-04 Wed 11:35]
     #+begin_src scheme :exports both :results value :noweb-ref cont-frac-recursive
  (define (cont-frac n d k)
    (define (next step)
      (if (< step k)
	  (/ (n step) (+ (d step) (next (+ step 1))) )
	  0))
    (next 1))
     #+end_src
    
     #+begin_src scheme :exports both :results value
     <<cont-frac-recursive>>
         (/ 1 (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 14))
     #+end_src

     #+RESULTS:
     : 1.6180257510729614

Abelson and Sussman tell us to estimate \(k\) needed to approximate the \(\varphi\) to a required
degree (0.0001). I didn't manage to derive the formula myself, however, I can
give a link to the book where this proof is given:

Khinchin, Continued Fractions (1935), chapter 2, section 7, gives an upper
bound on the speed of convergence as \(\frac{1}{k^2}\). Therefore we should
expect \(k \approx \sqrt{1000} \approx 33\). This holds for an arbitrary convergent
continued fraction. In our case, however, when \(N_k=D_k=1\), the constant in
the rate is also known as \(\sqrt{5}\), so the equation we need to solve is
in fact \(k^2 \sqrt{5} = 1000\), and in practice that is
\(\sqrt{\frac{1000}{2.23}} = 21\). How exactly we managed to do it in 14
steps, I don't know.

**** DONE b. iterative
     CLOSED: [2019-09-04 Wed 11:35]

We just start computing from the end.

#+begin_src scheme :exports both :results value :noweb-ref cont-frac
  (define (cont-frac n d k)
    (define (next step accumulator)
      (if (> step 0)
	  (next (- step 1) (/ (n step) (+ (d step) accumulator)))
	  accumulator))
    (next k 0))
#+end_src

#+RESULTS:
: #<undef>
  
#+begin_src scheme :exports both :results value
<<cont-frac>>
  (/ 1 (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) 14))
#+end_src

#+RESULTS:
: 1.6180371352785146


Remark: this exercise took me 7 hours.

*** DONE Exercise 1.38 euler constant
    CLOSED: [2019-09-04 Wed 11:35]

The only difficulty with this exercise is to derive the formula for the
second lambda.

#+begin_src scheme :exports both :results value
  <<cont-frac>>
  (+ 2 
     (cont-frac 
      (lambda (i) 1.0)
      (lambda (i) (if (= (remainder i 3) 2) (+ (* (/ i 3) 2) 2) 1))
      14 ))
#+end_src

#+RESULTS:
: 2.794771662537

*** DONE Exercise 1.39 tan-cf
    CLOSED: [2019-09-04 Wed 12:11]
    :LOGBOOK:

    :END:
#+begin_src scheme :exports both :results output
  <<cont-frac>>
  (define (tan-cf x k)
    (cont-frac
     (lambda (i)
       (if (= i 1) x (- (* x x))))
     (lambda (i)
       (- (* 2 i) 1))
     k))
  (display (tan 0.1))
  (newline)
  (display(tan-cf 0.1 300))
#+end_src

#+RESULTS:
: 0.10033467208545055
: 0.10033467208545055

*** DONE Exercise 1.40 newtons-method
    CLOSED: [2019-09-04 Wed 17:06]
    :LOGBOOK:
    CLOCK: [2019-09-04 Wed 17:21]--[2019-09-04 Wed 17:21] =>  0:00
    :END:

#+begin_src scheme :exports both :results value :noweb-ref deriv
  (define (deriv g)
    (lambda (x) (/ (- (g (+ x dx)) (g x)) dx)))
  (define dx 0.00001)
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref newtons-method
  (define (newton-transform g)
    (lambda (x) (- x (/ (g x) ((deriv g) x)))))
  (define (newtons-method g guess)
    (fixed-point (newton-transform g) guess))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref square
(define (square x)
 (* x x))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref cube
(define (cube x)
  (* x x x))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref cubic
  (define (cubic a b c) 
    (lambda (x) (+ (cube x) (* a (square x)) (* b x) c)))x
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref inc
(define (inc x) (+ x 1))
#+end_src

#+begin_src scheme :exports both :results output
<<fixed-point-silent>>
<<cubic>>
<<cube>>
<<square>>
<<deriv>>
<<newtons-method>>

(display (newtons-method (cubic 5 3 1) 1))
#+end_src

#+RESULTS:
: -4.365230013403046

Theoretically, a cubic may have up to 3 roots, but to find all of them we
would need to try over all possible ones.

*** DONE Exercise 1.41 double-double
    CLOSED: [2019-09-04 Wed 17:21]

#+begin_src scheme :exports both :results value :noweb-ref double-function
(define (double fun)
  (lambda (x) (fun (fun x))))
(define (inc x)
  (+ x 1))
#+end_src

#+begin_src scheme :exports both :results value
<<double-function>>
(((double double) inc) 5)
#+end_src

#+RESULTS:
: 9

#+begin_src scheme :exports both :results value
<<double-function>>
(((double (double double)) inc) 5)
#+end_src

#+RESULTS:
: 21

\(21 = 5 + 16\)
Double really works as a power of a function. \( 2 \Rightarrow 2^2 \Rightarrow2^{2^2} =
\mbox{inc}^{16} 5 \)
*** DONE Exercise 1.42 compose
    CLOSED: [2019-09-04 Wed 17:27]
#+begin_src scheme :exports both :results value :noweb-ref compose
(define (compose f g)
  (lambda (x) (f (g x))))
#+end_src

#+begin_src scheme :exports both :results value
<<compose>>
<<square>>
<<inc>>
((compose square inc) 6)
#+end_src

#+RESULTS:
: 49

*** DONE Exercise 1.43 repeated
    CLOSED: [2019-09-04 Wed 17:54]
#+begin_src scheme :exports both :results value :noweb-ref repeated

  (define (repeated fun n)
    (define (repeat-it n fun combinator)
      (if (= n 1)
	  combinator
	  (repeat-it  (- n 1) fun (lambda (x) (fun (combinator x))))))
      (repeat-it n fun fun))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value
<<repeated>>

<<square>>

((repeated square 2) 5)
#+end_src

#+RESULTS:
: 625

Hm. Managed to do it without the ~compose~ form.

*** DONE Exercise 1.44 smoothing
    CLOSED: [2019-09-04 Wed 20:17]

#+begin_src scheme :exports both :results value :noweb-ref smooth
  (define dx 0.1)
  (define (smooth f)
    (lambda (x) (/ (+ (f (- x dx))
		 (f x)
		 (f (+ x dx)))
	      3)))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref n-smoothed
  (define (n-smoothed fun n)
    ((repeated smooth n) fun))
#+end_src

#+begin_src scheme :exports both :results output
<<smooth>>
<<n-smoothed>>
<<repeated>>
<<cube>>
(define (ex144-answer x)
  ((n-smoothed cube 3) x))
(display (ex144-answer 10))
#+end_src

#+RESULTS:
: 1000.6

Looks like what we wanted.

*** DONE Exercise 1.45 nth-root
    CLOSED: [2019-09-04 Wed 21:37]

#+begin_src scheme :exports both :results value :noweb-ref average
(define (average x y)
   (/ (+ x y) 2))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref average-damp
(define (average-damp f)
  (lambda (x) (average x (f x))))
#+end_src


#+begin_src scheme :exports both :results value :noweb-ref n-average-damp
(define (n-average-damped f n)
   ((repeated average-damp n) f))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref better-fixed-point
  (define tolerance 0.0001)
  (define (fixed-point f first-guess)
    (define (close-enough? v1 v2)
      (< (abs (- v1 v2))
	 tolerance))
    (define (try guess)
       (let ((next (f guess)))
	(if (close-enough? guess next)
	    next
	    (try next))))
  (try first-guess))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value :noweb-ref root-n-x
  (define (root n x initial-guess)
    (fixed-point
     (n-average-damped
      (lambda (y) (/ x (pow y (- n 1))))
      n) 
      initial-guess))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref pow-recursive
(define (pow x n)
 (if (= n 1)
   x
   (* x (pow x (- n 1)))))
#+end_src

#+begin_src scheme :exports both :results output
<<average>>
<<average-damp>>
<<repeated>>
<<better-fixed-point>>
<<n-average-damp>>
<<pow-recursive>>
<<root-n-x>>
(display (root 4 4 3.0))

#+end_src

#+RESULTS:
: 1.4144444873765194

The true answer would require to actually estimate the dampening factor, but
we know that *n* is enough, and I am lazy.

*** DONE Exercise 1.46 iterative-improve
    CLOSED: [2019-09-04 Wed 22:25]

#+begin_src scheme :exports both :results value :noweb-ref iterative-improve
  (define (iterative-improve good-enough? improve)
    (define (improver guess)
      (if (good-enough? guess)
	  guess
	  (improver (improve guess))))
  improver)
#+end_src

**** DONE a. sqrt
     CLOSED: [2019-09-04 Wed 22:24]

#+begin_src scheme :exports both :results value
    <<square>>
    <<iterative-improve>>
    (define (ex1.46sqrt x)
      (let (
	    (square-improver
	     (iterative-improve
	      (lambda (y) (< (abs (- (square y) x )) 0.01))
	      (lambda (y) (/ (+ y (/ x y)) 2)))
	     )
	    )
	(square-improver 1)))
    (ex1.46sqrt 2.0)
#+end_src

#+RESULTS:
: 1.4166666666666665

**** DONE b. fixed-point
     CLOSED: [2019-09-04 Wed 22:25]

#+begin_src scheme :exports both :results value
    <<square>>
    <<iterative-improve>>
    (define (fixpoint f)
      (let (
	    (fixpoint-improver
	     (iterative-improve
	      (lambda (y) (< (abs (- (f y) y )) 0.01))
	      (lambda (y) (/ (+ y (f y)) 2)))
	     )
	    )
	(fixpoint-improver 1.0)))
    (fixpoint (lambda (x) (+ 1 (/ 1 x))))
#+end_src

#+RESULTS:
: 1.6147785476652068



I have made it. At [2019-09-04 Wed 22:25] I still haven't implemented all the
pictures, but I already can say that I have solved _all_ problems of the
first chapter of SICP. Some macros are wrong, I need to revise them, but that
will be done on the second pass. (Yes, there will be a second [or, rather, third] pass!)

** TODO Chapter 2: Building abstractions with data [106/110]
*** DONE Exercise 2.1 make-rat
    CLOSED: [2019-09-06 Fri 13:00]


In this exercise I will also define the functions presented by Abelson
and Sussman for general reference.

#+begin_src scheme :exports both :results value :noweb-ref make-rat
  (define (make-rat numerator denominator)
    (let* ((my-gcd (gcd numerator denominator))
	   (numerator (/ numerator my-gcd))
	   (denominator (/ denominator my-gcd))
	   (sign (/ (abs denominator) denominator)))
      (cons (* numerator sign) (* denominator sign))))
  (define (numer x)
    (car x))

  (define (denom x)
    (cdr x))

#+end_src

#+RESULTS:
: unfinished

#+begin_src scheme :exports both :results value 2.2.1-basic-rat
  (define (add-rat x y)
    (make-rat (+ (* (numer x) (denom y))
		 (* (numer y) (denom x)))
	      (* (denom x) (denom y))))
  (define (sub-rat x y)
    (make-rat (- (* (numer x) (denom y))
		 (* (numer y) (denom x)))
	      (* (denom x) (denom y))))
  (define (mul-rat x y)
    (make-rat (* (numer x) (numer y))
	      (* (denom x) (denom y))))

  (define (div-rat x y)
    (make-rat (* (numer x) (denom y))
	      (* (denom x) (numer y))))
  (define (equal-rat? x y)
    (= (* (numer x) (denom y))
       (* (numer y) (denom x))))

#+end_src

#+begin_src scheme :exports both :results value :noweb-ref print-rat
  (define (print-rat x)
    (newline)
    (display (numer x))
    (display "/")
    (display (denom x)))
#+end_src

#+begin_src scheme :exports both :results output
<<print-rat>>
<<2.2.1-basic-rat>>
<<make-rat>>
(define one-half (make-rat -65 -5))
(print-rat one-half)
#+end_src

#+RESULTS:
: 
: 13/1

*** TODO Figure 2.1

This figure contains a data-abstraction diagram. I don't know how to
make them yet.

*** DONE Exercise 2.2 make-segment
    CLOSED: [2019-09-06 Fri 13:34]

#+begin_src scheme :exports both :results value :noweb-ref make-segment
  (define (make-segment x1 y1 x2 y2)
    (cons (make-point x1 y1)  (make-point x2 y2)))

  (define (start-segment segment)
    (car segment))

  (define (end-segment segment)
    (cdr segment))

  (define (make-point x y)
    (cons x y))

  (define (x-point point)
    (car point))

  (define (y-point point)
    (cdr point))

  (define (midpoint-segment segment)
    (make-point (/ (+ (x-point (start-segment segment))
		   (x-point (end-segment   segment))) 2)
		(/ (+ (y-point (start-segment segment))
		   (y-point (end-segment   segment))) 2)))

#+end_src

#+begin_src scheme :exports both :results value :noweb-ref print-point
  (define (print-point p)
    (newline)
    (display "(")
    (display (x-point p))
    (display ",")
    (display (y-point p))
    (display ")"))
#+end_src

#+begin_src scheme :exports both :results output
<<print-point>>
<<make-segment>>
(print-point (midpoint-segment (make-segment 1 0 0 1)))
#+end_src

#+RESULTS:
: 
: (1/2,1/2)

The task looks pretty straightforward. Just make a cons of points.

*** DONE Exercise 2.3 make-rectangle
    CLOSED: [2019-09-08 Sun 17:58]

I will choose the following two representations:
 - List of points from top left to the right.
 - Two lists of coordinates, x and y.

I will not be using segments from Exercise 2.2, because then I would
have to care about the consistency of the first and the last point in
the four segments.

#+begin_src scheme :exports both :results output :noweb-ref rectangle
  (define (area rectangle)
    (* (get-height rectangle) (get-width rectangle)))
  (define (perimeter rectangle)
    (* 2 (+ (get-height rectangle) (get-width rectangle))))
  (define (get-height rectangle)
    (dist (nth-point 1 rectangle) (nth-point 2 rectangle)))
  (define (get-width rectangle)
    (dist (nth-point 2 rectangle) (nth-point 3 rectangle)))
  (define (dist point1 point2)
    (+ (square (- (x-point point1) (x-point point2))) (square (- (y-point point1) (y-point point2)))))

#+end_src

#+begin_src scheme :exports both :results output :noweb-ref rectangle-point-list
  (define (make-rectangle x1 y1 x2 y2 x3 y3 x4 y4)   
    (list (make-point x1 y1)
	  (make-point x2 y2)
	  (make-point x3 y3)
	  (make-point x4 y4)))
  (define (nth-point n rectangle)
    (if (= n 1)
	(car rectangle)
	(nth-point (- n 1) (cdr rectangle))))
#+end_src


#+begin_src scheme :exports both :results output :noweb-ref rectangle-two-lists
  (define (make-rectangle x1 y1 x2 y2 x3 y3 x4 y4)   
    (cons (list x1 x2 x3 x4) (list y1 y2 y3 y4)))

  (define (nth-point n rectangle)
    (if (= n 1)
	(make-point (caar rectangle) (cadr rectangle))
	(nth-point (- n 1) (cons (cdar rectangle) (cddr rectangle)))))
#+end_src

#+begin_src scheme :exports both :results output
  <<rectangle>>
  <<rectangle-point-list>>
  <<make-segment>>
  (let ((test1 (make-rectangle 0 0 0 1 1 1 1 0)))
    (display "Area=")
    (display (area test1))
    (newline)
    (display "Perimeter=")
    (display (perimeter test1))
    (newline))

#+end_src

#+RESULTS:
: Area=1
: Perimeter=4


#+begin_src scheme :exports both :results output
  <<rectangle>>
  <<rectangle-two-lists>>
  <<make-segment>>
  (let ((test1 (make-rectangle 0 0 0 1 1 1 1 0)))
    (display "Area=")
    (display (area test1))
    (newline)
    (display "Perimeter=")
    (display (perimeter test1))
    (newline))

#+end_src

#+RESULTS:
: Area=1
: Perimeter=4

This is not very efficient, but two implementations were requested --
and they were delivered.

*** DONE Exercise 2.4 cons-lambda
    CLOSED: [2019-09-08 Sun 18:08]

#+begin_src scheme :exports both :results output
  (define (cons x y)
    (lambda (m) (m x y)))
  (define (car z)
    (z (lambda (p q) p)))
  (define (cdr z)
    (z (lambda (p q) q)))

  (display (car (cons 'a 'b)))
  (newline)
  (display (cdr (cons 'a 'b)))
  (newline)
#+end_src

#+RESULTS:
: a
: b

*** DONE Exercise 2.5 cons-pow
    CLOSED: [2019-09-08 Sun 19:07]
    0:00:00 -- 0:56:02 

#+begin_src scheme :exports both :results value :noweb-ref ex2.5cons
(define (cons a b)
  (* (expt 2 a) (expt 3 b)))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value :noweb-ref ex2.5car
(define (car number)
  (log (gcd (expt 2.0 (floor (log number 2))) number) 2))
(define (cdr number)
  (log (gcd (expt 3.0 (floor (log number 2))) number) 3))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value
<<ex2.5car>>
<<ex2.5cons>>

(list (car (cons 14 4)) (cdr (cons 14 4)))

#+end_src

#+RESULTS:
| 14.0 | 4.0 |

*** DONE Exercise 2.6 Church Numerals
    CLOSED: [2019-09-08 Sun 19:41]
0:00:00 -- 0:23:58 

In the worst case this exercise can be copied literally right from the
Wikipedia article: https://en.wikipedia.org/wiki/Church_encoding
#+begin_src scheme :exports both :results value :noweb-ref church-zero
  (define identity (lambda (x) x))
  (define zero (lambda (f) identity))
  (define (add-1 n)
    (lambda (f) (lambda (x) (f ((n f) x)))))
#+end_src

#+begin_src scheme :exports both :results output
  <<church-zero>>
  (define one (lambda (f) (lambda (x) (f x))))
  (define two (lambda (f) (lambda (x) (f (f x)))))
  (define (plus a b)
    (lambda (f) (lambda (x) ((a f) ((b f) x)))))

#+end_src

#+RESULTS:

*** DONE Exercise 2.7 make-interval
    CLOSED: [2019-09-08 Sun 20:09]
0:00:00 -- 0:20:09 

#+begin_src scheme :exports both :results value :noweb-ref make-interval
  (define (make-interval a b)
    (cons a b))
  (define (upper-bound interval)
    (max (car interval) (cdr interval)))
  (define (lower-bound interval)
    (min (car interval) (cdr interval)))
#+end_src


#+begin_src scheme :exports both :results value :noweb-ref interval-common
  (define (add-interval x y)
    (make-interval (+ (lower-bound x) (lower-bound y))
		   (+ (upper-bound x) (upper-bound y))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref mul-interval-simple
  (define (mul-interval x y)
    (let ((p1 (* (lower-bound x) (lower-bound y)))
	  (p2 (* (lower-bound x) (upper-bound y)))
	  (p3 (* (upper-bound x) (lower-bound y)))
	  (p4 (* (upper-bound x) (upper-bound y))))
      (make-interval (min p1 p2 p3 p4)
		     (max p1 p2 p3 p4))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref div-interval-lame
  (define (div-interval x y)
    (mul-interval
     x
     (make-interval (/ 1.0 (upper-bound y))
		    (/ 1.0 (lower-bound y)))))
#+end_src

#+begin_src scheme :exports both :results output
<<make-interval>>
<<interval-common>>
<<div-interval-lame>>
<<mul-interval-simple>>
(show #t " " (add-interval (make-interval 5 5.6) (make-interval 6 6.1)) "\n")
(show #t " " (mul-interval (make-interval -0.1 0.1) (make-interval 100 110)) "\n")
(show #t " " (div-interval (make-interval -0.1 0.1) (make-interval 100 110)))
#+end_src

#+RESULTS:
:  (11.0 . 11.7)
:  (-11.0 . 11.0)
:  (-0.001 . 0.001)

*** DONE Exercise 2.8 sub-interval
    CLOSED: [2019-09-08 Sun 23:07]

#+begin_src scheme :exports both :results value :noweb-ref sub-interval
  (define (sub-interval a b)
    (make-interval (- (upper-bound a) (lower-bound b))
		   (- (lower-bound a) (upper-bound b))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<make-interval>>
<<sub-interval>>
(show #t " " (sub-interval (make-interval 100 -100) (make-interval -1 101)))
#+end_src

#+RESULTS:
:  (101 . -201)

*** DONE Exercise 2.9 interval-width
    CLOSED: [2019-09-08 Sun 23:15]
 0:06:00
#+begin_src scheme :exports both :results value
  (define (width interval)
    (abs (- (upper-bound interval) (lower-bound interval))))
#+end_src

\( a + \Delta a + b + \Delta b = (a+b) + (\Delta a + \Delta b)\)
\((a+\Delta a)\cdot (b+\Delta b) = (a\cdot b) + (a\Delta b + b\Delta a + \Delta a \Delta b)\)

The formulae above should relatively convincingly explain why the
width is not the function of the initial widths only in the case of
multiplication. 

*** DONE Exercise 2.10 div-interval-better
    CLOSED: [2019-09-08 Sun 23:30]
0:14:50  
The initial Alyssa's construction is:
#+begin_src scheme :exports both :results value :noweb-ref div-interval-better
  (define (div-interval x y)
    (when (and (< (lower-bound y) 0) (> (upper-bound y) 0))
      (error "Division by zero." (list x y)))
      (mul-interval
       x
       (make-interval (/ 1.0 (upper-bound y))
		      (/ 1.0 (lower-bound y)))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<div-interval-better>>
<<make-interval>>
(display (div-interval (make-interval 1 2) (make-interval -1 1)))
#+end_src

#+RESULTS:
: '(Exception #19 user "Division by zero." (((1 . 2) (-1 . 1))) #f #f)

*** DONE Exercise 2.11 mul-interval-nine-cases
    CLOSED: [2019-09-09 Mon 00:45]
1:06:58 

| number | lower x | upper x | lower y | upper y |
|--------+---------+---------+---------+---------|
|      2 | +       | +       | +       | +       |
|      2 | +       | +       | -       | +       |
|      2 | +       | +       | -       | -       |
|      2 | -       | +       | +       | +       |
|      3 | -       | +       | -       | +       |
|      2 | -       | +       | -       | -       |
|      2 | -       | -       | +       | +       |
|      2 | -       | -       | -       | +       |
|      2 | -       | -       | -       | -       |


#+begin_src scheme :exports both :results value :noweb-ref mul-interval
  (define (mul-interval x y)
    (let ((x1 (lower-bound x))
	  (x2 (upper-bound x))
	  (y1 (lower-bound y))
	  (y2 (upper-bound y)))
      (cond ((and (> x1 0) (> x2 0) (> y1 0) (> y2 0)) (make-interval (* x1 y1) (* x2 y2)))
	    ((and (> x1 0) (> x2 0) (< y1 0) (> y2 0)) (make-interval (* x2 y1) (* x2 y2)))
	    ((and (> x1 0) (> x2 0) (< y1 0) (< y2 0)) (make-interval (* x2 y1) (* x2 y1)))
	    ((and (< x1 0) (> x2 0) (> y1 0) (> y2 0)) (make-interval (* x1 y2) (* x2 y2)))
	    ((and (< x1 0) (> x2 0) (< y1 0) (> y2 0))
	     (let ((p1 (* (lower-bound x) (lower-bound y)))
		   (p2 (* (lower-bound x) (upper-bound y)))
		   (p3 (* (upper-bound x) (lower-bound y)))
		   (p4 (* (upper-bound x) (upper-bound y))))
	       (make-interval (min p1 p2 p3 p4)
			      (max p1 p2 p3 p4))))
	    ((and (< x1 0) (> x2 0) (< y1 0) (< y2 0)) (make-interval (* x2 y2) (* x2 y1)))
	    ((and (< x1 0) (< x2 0) (> y1 0) (> y2 0)) (make-interval (* x1 y2) (* x2 y1)))
	    ((and (< x1 0) (< x2 0) (< y1 0) (> y2 0)) (make-interval (* x2 y2) (* x1 y1)))
	    ((and (< x1 0) (< x2 0) (< y1 0) (< y2 0)) (make-interval (* x2 y2) (* x1 y1))))))
#+end_src

I don't even want to test it. 

#+begin_src scheme :exports both :results output
<<mul-interval>>
<<make-interval>>
(show #t " " (mul-interval (make-interval -2 2) (make-interval -5 6)))

#+end_src

#+RESULTS:
:  (-12 . 12)

Marvelous.

*** DONE Exercise 2.12 make-center-percent
    CLOSED: [2019-09-09 Mon 10:11]

#+begin_src scheme :exports both :results value :noweb-ref make-center-width
  (define (make-center-width c w)
    (make-interval (- c w) (+ c w)))
  (define (center i)
    (/ (+ (lower-bound i) (upper-bound i)) 2))
  (define (width i)
    (/ (- (upper-bound i) (lower-bound i)) 2))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref make-center-precision
  (define (make-center-percent center percent)
    (let ((delta (* center (/ percent 100))))
      (make-interval  (+ center delta) (- center delta))))
  (define (relative-precision interval)
    (let* ((center (/ (+ (lower-bound interval) (upper-bound interval))
		     2))
	   (percent (/ (abs (- (lower-bound interval) (upper-bound interval))) 2)))
      (/ percent center)))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<make-center-width>>
<<make-center-precision>>
<<make-interval>>
  (let ((test-interval (make-center-percent 100 2)))
    (show #t " " test-interval "\n")
    (show #t " " (center test-interval) "\n")
    (show #t " " (relative-precision test-interval)) "\n")
#+end_src

#+RESULTS:
:  (102 . 98)
:  100
:  1/50

*** DONE Exercise 2.13 formula for tolerance
    CLOSED: [2019-09-09 Mon 10:16]

\((a+\Delta a)\cdot (b+\Delta b) = (a\cdot b) + (a\Delta b + b\Delta a + \Delta a \Delta b)\)
\(\frac{(a+\Delta a)\cdot (b+\Delta b)}{a\cdot b} = \frac{(a\cdot b)}{a\cdot b} + \frac{(a\Delta b +
b\Delta a + \Delta a \Delta b)}{a \cdot b} \approx 1 + \frac{\Delta a}{a} + \frac{\Delta b}{b}\) 

*** DONE Exercise 2.14 parallel-resistors
    CLOSED: [2019-09-09 Mon 11:24]
0:37:00 +  0:31:07 = 1:06:07
#+begin_src scheme :exports both :results output
  <<make-interval>>
  <<div-interval-better>>
  <<mul-interval>>
  <<interval-common>>
  (define (par1 r1 r2)
    (div-interval (mul-interval r1 r2)
		  (add-interval r1 r2)))
  (define (par2 r1 r2)
    (let ((one (make-interval 1 1)))
      (div-interval
       one (add-interval (div-interval one r1)
			 (div-interval one r2)))))

  (show #t " " (par1 (make-interval 4.9 5.1) (make-interval 6.9 7.1)) "\n")
  (show #t " " (par2 (make-interval 4.9 5.1) (make-interval 6.9 7.1)) "\n")
#+end_src

#+RESULTS:
:  (2.7713114754098367 . 3.0686440677966096)
:  (2.8652542372881356 . 2.968032786885246)

It is worth noticing that ~par2~ uses more operations than
~par1~. Even if the title problem in the exercise wasn't present, we
would still get a less precise result.

#+begin_src scheme :exports both :results output
    <<make-interval>>
    <<mul-interval>>
    <<div-interval-better>>
    (let ((one (make-interval 1.0 1.0))
	  (i2 (make-interval 4.9 5.1))
	  (i3 (make-interval 6.9 7.1)))
      (show #t " " (div-interval one one) "\n")
      (show #t " " (div-interval one i2) "\n")
      (show #t " " (div-interval i2 i2) "\n")
      (show #t " " (div-interval i2 i3) "\n")
      (show #t " " (mul-interval  i2 (div-interval one i2)) "\n"))

#+end_src

#+RESULTS:
:  (1.0 . 1.0)
:  (0.19607843137254904 . 0.2040816326530612)
:  (0.9607843137254903 . 1.040816326530612)
:  (0.6901408450704226 . 0.7391304347826086)
:  (0.9607843137254903 . 1.040816326530612)

The idea here is, in some sense, the non-independence of the random
variables *i2* and *i2*. Regardless of the precision of *i2*, we
_know_ that \(\frac{i_2}{i_2} = 1\). 

The center-percent form I implemented is slightly different from the
one Abelson expected, I guess, but still,
\(\frac{1}{1} \approx 1 \pm 2\Delta\). This is too much.

*** DONE Exercise 2.15 better-intervals
    CLOSED: [2019-09-09 Mon 11:34]

I already answered this question in the Exercise 2.14. The problem is
of the potential independence (which may or may not be the case) of
*a* and *b*, but complete dependence of *a* on *a*, which is \(1\)
regardless of whether *a* is even well-defined.

*** DONE Exercise 2.16 interval-arithmetic
    CLOSED: [2019-09-09 Mon 11:37]

To solve this problem in the general case, on would have to build a
probability distribution of the function on the variables, and use
something of a probabilistic reduction on every step. I am not aware
of such systems if they even exist. It would be indispensable for
quantum modelling though.

Hypothetically, if such systems existed, they would do something like
build a distribution on every step of the computation and track every
quantity occurrence in every distribution.

*** TODO Figure 2.2 Box-and-pointer representation of ~(cons 1 2)~. :graphviz:plantuml:tikz:
https://gitlab.com/graphviz/graphviz/issues/1588
https://gitlab.com/graphviz/graphviz/issues/1589
10:00:00
[2019-09-10 Tue 10:24] I managed to make pgf work with org-mode, but
didn't manage to  make a picture yet. So far this problem happened to
generalize to the case of drawing arbitrary vector graphics. Graphviz
turned out to be less fit for this problem.

#+begin_src plantuml :exports both :file figure-2-2.png
  @startdot
  digraph sicp2_2 {
    node [shape=none];
    source [label=""];
    
    node [shape=plaintext, style="rounded"];
    struct0 [label=<<table BORDER="0" CELLBORDER="1" CELLSPACING="0">
             <tr>
                 <td width="29" height="35" sides="ltrb" port="f1"></td>
                 <td width="29" height="35" sides="lrtb" port="f2"></td>
             </tr>
             </table>>, style="rounded,filled", fillcolor="gray"];
    rankdir=LR;
    node [shape=record, style="rounded"];
    struct2 [label="<f2> 2"];
    struct1 [label="<f1> 1"];
    edge [arrowhead=normal,arrowtail=dot];    
    struct0:f2:c -> struct2:f0 [tailclip=false];
    struct0:f1:c -> struct1:f0 [tailclip=false];
    source -> struct0;
  }

  @enddot
#+end_src 

#+RESULTS:
[[file:figure-2-2.png]]



#+name: tikztest
#+header: :imagemagick yes :iminoptions -density 600 :imoutoptions -geometry 200
#+header: :fit yes :headers '("\\usepackage{tikz}")
#+header: :buffer on
#+begin_src latex :results raw file :exports code :file test.png
  \usetikzlibrary{trees}
  \begin{tikzpicture}[color=white]
    \node [circle, draw, fill=red!70] at (0,0) {1}
      child { 
             node [circle, draw, fill=blue!70] {2}
             child { 
                   node [circle, draw, fill=green!70]  {3} }
             child { 
                   node [circle, draw, fill=yellow!70] {4} }
            };
  \end{tikzpicture}
#+end_src

#+RESULTS: tikztest
[[file:test.png]]


#+begin_src plantuml :exports both :file ditaa.png
@startditaa
               +---+---+     +---+---+         +---+---+     +---+
          ---->| * | *-+---->| * | * |    ---->| * | *------>| 4 |
               +-|-+---+     +-|-+-|-+         +-|-+---+     +---+
                 |             |   |             |
                 V             V   V             V
             +---+---+      +---+ +---+      +---+---+     +---+---+
             | * | * |      | 3 | | 4 |      | * | *-+---->| * | * |
             +-|-+-|-+      +---+ +---+      +-|-+---+     +-|-+-|-+
               |   |                           |             |   |
               V   V                           V             V   V
            +---+ +---+                      +---+        +---+ +---+
            | 1 | | 2 |                      | 1 |        | 2 | | 3 |
            +---+ +---+                      +---+        +---+ +---+

@endditaa
#+end_src 

#+RESULTS:
[[file:ditaa.png]]

*** DONE Exercise 2.17 last-pair
    CLOSED: [2019-09-10 Tue 10:48]
0:20:51 

#+begin_src scheme :exports both :results value :noweb-ref last-pair
  (define (last-pair lst)
    (list-tail lst (- (length lst) 1)))
#+end_src

#+begin_src scheme :exports both :results output
<<last-pair>>
(let ((tmp (last-pair '(1 1))))
(show #t " " (car tmp) " " (cdr tmp)))
#+end_src

#+RESULTS:
:  1 ()

*** DONE Exercise 2.18 reverse
    CLOSED: [2019-09-10 Tue 10:57]
0:03:56 
#+begin_src scheme :exports both :results value :noweb-ref reverse-list
  (define (reverse lst)
    (define (lst-iter x y)
       (if (null? y)
	   x
	   (lst-iter (cons (car y) x) (cdr y))))
    (lst-iter '() lst))
#+end_src

#+begin_src scheme :exports both :results output
<<reverse-list>>
(show #t " " (reverse '(1 2 3)))
#+end_src

#+RESULTS:
:  (3 2 1)

*** DONE Exercise 2.19 coin-values                                   :unsure:
    CLOSED: [2019-09-10 Tue 11:27]

#+begin_src scheme :exports both :results value :noweb-ref coin-values
  (define us-coins (list 50 25 10 5 1))
  (define uk-coins (list 100 50 20 10 5 2 1 0.5))
  (define uk-coins-damaged (list 0.50 100 50 20 10 5 2 1))

  (define (cc amount coin-values)
    (cond ((= amount 0) 1)
	  ((or (< amount 0) (no-more? coin-values)) 0)
	  (else
	   (+ (cc amount
		  (except-first-denomination
		   coin-values))
	      (cc (- amount
		     (first-denomination
		      coin-values))
		  coin-values)))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref first-denomination
  (define (first-denomination coin-values)
    (car coin-values))
  (define (except-first-denomination coin-values)
    (cdr coin-values))
  (define (no-more? coin-values)
    (null? coin-values))
#+end_src

*Warning:* the next code is a bit slow (~1 minute).

#+begin_src scheme :exports both :results output
<<first-denomination>>
<<coin-values>>
(show #t " " (cc 137 us-coins) "\n")
(show #t " " (cc 137 uk-coins) "\n")
#+end_src

#+RESULTS:
:  704
:  443166

#+begin_src scheme :exports both :results output
<<first-denomination>>
<<coin-values>>
(show #t " " (cc 137 uk-coins-damaged) "\n")
#+end_src

#+RESULTS:
:  443166

I don't see why the result would depend on the order of the coins. We
don't seem to be using the order anywhere.

*** DONE Exercise 2.20 dotted-tail notation
    CLOSED: [2019-09-10 Tue 18:55]
1:45:10 
#+begin_src scheme :exports both :results value :noweb-ref same-parity
  (define (same-parity . lst)
    (define (iter-parity lst bit accumulator)
      (cond ((null? lst)
	     accumulator)
	    ((= (remainder (car lst) 2) bit)
	     (iter-parity (cdr lst) bit (cons (car lst) accumulator)))
	    (else
	     (iter-parity (cdr lst) bit accumulator))))
   (reverse (iter-parity lst (remainder (car lst) 2) '())))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<same-parity>>
(show #t " " (same-parity 2 3 4) "\n")
(show #t " " (same-parity 1 2 3 4) "\n")
#+end_src

#+RESULTS:
:  (2 4)
:  (1 3)

*** DONE Exercise 2.21 map-square-list
    CLOSED: [2019-09-10 Tue 19:14]
0:13:23 
#+begin_src scheme :exports both :results output
  (define nil #f)
  (define (square-list items)

  (if (null? items)
	'()
	(cons (* (car items) (car items)) (square-list (cdr items)))))
  (show #t " " (square-list '(1 2 3 4 5)))
#+end_src

#+RESULTS:
:  (1 4 9 16 25)

#+begin_src scheme :exports both :results output
  (define (square-list items)
    (map (lambda (x) (* x x)) items))

  (show #t " " (square-list '(1 2 3 4 5)))
#+end_src

#+RESULTS:
:  (1 4 9 16 25)

One of the peculiar tricks in this equation is that unlike in older
lisps, *#f* is not entirely the same as ~'()~, although they both
evaluate to false.

*** DONE Exercise 2.22 wrong list order
    CLOSED: [2019-09-10 Tue 19:24]
Referring to Exercise 2.20 is highly recommended. 

The problem with the first solution is that, indeed, he's ~cons~'ing
the pair in such a way that it would produce the reversed list.

The problem with the second solution is that it IS creating a list-ish
construction that is contains all the elements in the right order, but
stores them in ~cdr~'s, not in ~car~'s. 

In lisp without mutations (without ~set-cdr!~ and ~set-car!~), it is
only possible to prepend elements to lists, not really append.

*** DONE Exercise 2.23 for-each
    CLOSED: [2019-09-10 Tue 19:33]
0:04:56 
#+begin_src scheme :exports both :results output
  (define (for-each fun items)
   (unless (null? items)
    (fun (car items))
    (for-each fun (cdr items))))

  (for-each (lambda (x)
	      (newline)
	      (display x))
	    (list 57 321 88))
#+end_src

#+RESULTS:
: 
: 57
: 321
: 88

*** DONE Exercise 2.24 list-plot-result                            :graphviz:
    CLOSED: [2019-09-10 Tue 22:13]
0:48:39 
The result of the interpreter:
#+begin_src scheme :exports both :results output
(show #t " " (list 1 (list 2 (list 3 4))))
#+end_src

#+RESULTS:
:  (1 (2 (3 4)))

The box-and-pointer structure:

#+begin_src plantuml :exports both :file exercise-2-24.png
  @startdot
  digraph sicp2_24 {
    node [shape=plaintext, style="rounded"];
    struct1 [label=<<table BORDER="0" CELLBORDER="1" CELLSPACING="0">
             <tr>
                 <td width="29" height="35" sides="ltrb" port="f0">1</td>
                 <td width="29" height="35" sides="lrtb" port="f1"></td>
             </tr>
             </table>>, style="rounded,filled", fillcolor="gray"];
    rankdir=LR;
    edge [arrowhead=normal,arrowtail=dot,tailclip=false, dir=both];    
    struct1:f1:c -> struct2 [tailclip=false];
    
    node [shape=plaintext, style="rounded"];
    struct2 [label=<<table BORDER="0" CELLBORDER="1" CELLSPACING="0">
             <tr>
                 <td width="29" height="35" sides="ltrb" port="f0"></td>
                 <td width="29" height="35" sides="lrtb" port="f1">'()</td>
             </tr>
             </table>>, style="rounded,filled", fillcolor="gray"];
    
    struct2:f0:c -> struct3 [tailclip=false];
    
    node [shape=plaintext, style="rounded"];
    struct3 [label=<<table BORDER="0" CELLBORDER="1" CELLSPACING="0">
             <tr>
                 <td width="29" height="35" sides="ltrb" port="f0"></td>
                 <td width="29" height="35" sides="lrtb" port="f1"></td>
             </tr>
             </table>>, style="rounded,filled", fillcolor="gray"];

    node [shape=plaintext, style="rounded"];
    struct4 [label=<<table BORDER="0" CELLBORDER="1" CELLSPACING="0">
             <tr>
                 <td width="29" height="35" sides="ltrb" port="f0"></td>
                 <td width="29" height="35" sides="lrtb" port="f1">'()</td>
             </tr>
             </table>>, style="rounded,filled", fillcolor="gray"];
    struct3_3 [label="2",shape=record];
    struct3:f0:c -> struct3_3 [tailclip=false];

    struct3:f1:c -> struct4 [tailclip=false];

    struct5 [label=<<table BORDER="0" CELLBORDER="1" CELLSPACING="0">
             <tr>
                 <td width="29" height="35" sides="ltrb" port="f0">3</td>
                 <td width="29" height="35" sides="lrtb" port="f1"></td>
             </tr>
             </table>>, style="rounded,filled", fillcolor="gray"];
    struct4:f0:c -> struct5;    

    struct6 [label=<<table BORDER="0" CELLBORDER="1" CELLSPACING="0">
             <tr>
                 <td width="29" height="35" sides="ltrb" port="f0">4</td>
                 <td width="29" height="35" sides="lrtb" port="f1">'()</td>
             </tr>
             </table>>, style="rounded,filled", fillcolor="gray"];
    struct5:f1:c -> struct6;

  }

  @enddot
#+end_src 

#+RESULTS:
[[file:exercise-2-24.png]]

Tree interpretation:

 #+begin_src plantuml :exports both :file figure-1-1-dot.png
 @startdot
 graph g {
	 node [shape=plaintext];
	 A1 [label="(1 (2 (3 4)))"];

	 B1 [label="1"];
         B2 [label="(2 (3 4))"];

         C1 [label="2"];
         C2 [label="(3 4)"];

         D1 [label="3"];
         D2 [label="4"];


 // edges
	 A1 -- B1;
	 A1 -- B2;
	
	 B2 -- C1;
	 B2 -- C2;

	 C2 -- D1;
	 C2 -- D2;

	 { rank=same; A1 }
	 { rank=same; B1 B2 } 
	 { rank=same; C1 C2 }
	 { rank=same; D1 D2 }
 } 
 @enddot
 #+end_src 

 #+RESULTS:
 [[file:figure-1-1-dot.png]]

*** DONE Exercise 2.25 caddr
    CLOSED: [2019-09-10 Tue 23:07]
#+begin_src scheme :exports both :results value
(car (cdr (car (cdr (cdr '(1 3 (5 7) 9))))))
#+end_src

#+RESULTS:
: 7

#+begin_src scheme :exports both :results value
(caar '((7)))
#+end_src

#+RESULTS:
: 7

#+begin_src scheme :exports both :results output
(show #t " " (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr '(1 (2 (3 (4 (5 (6 7)))))))))))))))))))
#+end_src

#+RESULTS:
:  7

The task was funny.

*** DONE Exercise 2.26 append cons list
    CLOSED: [2019-09-10 Tue 23:23]

#+begin_src scheme :exports both :results output
(define x (list 1 2 3))
(define y (list 4 5 6))
(show #t " " (append x y) "\n")
(show #t " " (cons x y) "\n")
(show #t " " (list x y) "\n")
#+end_src

#+RESULTS:
:  (1 2 3 4 5 6)
:  ((1 2 3) 4 5 6)
:  ((1 2 3) (4 5 6))

*** DONE Exercise 2.27 deep-reverse
    CLOSED: [2019-09-11 Wed 09:47]
0:14:46 
#+begin_src scheme :exports both :results output
  (define (deep-reverse lst)
    (define (iter-reverse lst1 accumulator)
      (if (null? lst1)
	  accumulator
	  (if (pair? (car lst1))
	      (iter-reverse (cdr lst1) (cons (deep-reverse (car lst1)) accumulator))
	      (iter-reverse (cdr lst1) (cons (car lst1) accumulator)))))
    (iter-reverse lst '()))

  (define x (list (list 1 2) (list 3 4)))
  (show #t " " (reverse x) "\n")
  (show #t " " (deep-reverse x))
#+end_src

#+RESULTS:
:  ((3 4) (1 2))
:  ((4 3) (2 1))

*** DONE Exercise 2.28 fringe
    CLOSED: [2019-09-11 Wed 10:24]
0:37:00
#+begin_src scheme :exports both :results output
      (define (fringe tree)
	(define (fringe-iter tree accumulator)
	  (cond  ((null? tree) '())
		 ((not (pair? tree)) (list tree))
		 (else
		   (append accumulator 
			   (fringe-iter (car tree) '())
			   (fringe-iter (cdr tree) '())))))
	(fringe-iter tree '()))
      (define x (list (list 1 2) (list 3 4)))
      (show #t " " (fringe x) "\n")
      (show #t " " (fringe (list x x)) "\n")

#+end_src

#+RESULTS:
:  (1 2 3 4)
:  (1 2 3 4 1 2 3 4)

*** DONE Exercise 2.29 mobile
    CLOSED: [2019-09-11 Wed 11:47]
1:23:0
#+begin_src scheme :exports both :results value :noweb-ref mobile
  (define (make-mobile left right)
    (list left right))

  (define (make-branch length structure)
    (list length structure))

  (define (left-branch mobile)
    (car mobile))

  (define (right-branch mobile)
    (cadr mobile))

  (define (branch-length branch)
    (car branch))

  (define (branch-structure branch)
    (cadr branch))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref mobile-total-weight
  (define (total-weight mobile)
    (if (pair? mobile)
    (+ (if (pair? (branch-structure (left-branch mobile)))
	   (total-weight (branch-structure (left-branch mobile)))
	   (branch-structure (left-branch mobile)))
       (if (pair? (branch-structure (right-branch mobile)))
	   (total-weight (branch-structure (right-branch mobile)))
	   (branch-structure (right-branch mobile))))
    mobile))
#+end_src

#+begin_src scheme :exports both :results value
  <<mobile>>
  <<mobile-total-weight>>
  (total-weight
   (make-mobile
    (make-branch
     5
     (make-mobile
      (make-branch 1 1)
      (make-branch 2 2)))
    (make-branch 7 2)))
#+end_src

#+RESULTS:
: 5

#+begin_src scheme :exports both :results value :noweb-ref mobile-balanced
    (define (balanced? mobile)
      (and
       (=
	(*
	 (branch-length (left-branch mobile))
	 (total-weight (branch-structure (left-branch mobile))))
	(*
	 (branch-length (right-branch mobile))
	 (total-weight (branch-structure (right-branch mobile))))
	)
       (if (pair? (branch-structure (left-branch mobile)))
	   (balanced? (branch-structure (left-branch mobile)))
	   #t)
       (if (pair? (branch-structure (right-branch mobile)))
	   (balanced? (branch-structure (right-branch mobile)))
	   #t)))
     
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<mobile-balanced>>
<<mobile-total-weight>>
<<mobile>>
  (show #t " " (balanced?
   (make-mobile
    (make-branch
     5
     (make-mobile
      (make-branch 1 1)
      (make-branch 2 2)))
    (make-branch 7 2))) "\n")
  (show #t " " (balanced? (make-mobile (make-branch 5 5) (make-branch 5 5))) "\n")

#+end_src

#+RESULTS:
:  #f
:  #t

If we replace lists with ~cons~, the only thing that needs to be
changed is that ~cadr~ should be replaced with ~car~.

*** DONE Exercise 2.30 square-tree
    CLOSED: [2019-09-11 Wed 14:11]
 1. A no-high-level version
#+begin_src scheme :exports both :results value :noweb-ref  square-tree
  (define (square-tree tree)
    (cond ((null? tree) '())
	  ((not (pair? tree)) (square tree))
	  (else (cons (square-tree (car tree))
		      (square-tree (cdr tree))))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<square-tree>>
  (show #t " " (square-tree
   (list 1
	 (list 2 (list 3 4) 5)
	 (list 6 7))))
#+end_src

#+RESULTS:
:  (1 (4 (9 16) 25) (36 49))
 2. High-level version
#+begin_src scheme :exports both :results output :noweb-ref square-subtree-map
    (define (square-tree tree)
      (map (lambda (sub-tree)
	     (if (pair? sub-tree)
		 (square-tree sub-tree)
		 (square sub-tree)))
	   tree))

#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
<<square-subtree-map>>
  (show #t " " (square-tree
   (list 1
	 (list 2 (list 3 4) 5)
	 (list 6 7))))
#+end_src

#+RESULTS:
:  (1 (4 (9 16) 25) (36 49))

Not a very hard problem.

*** DONE Exercise 2.31 tree-map square tree
    CLOSED: [2019-09-11 Wed 14:38]
Not a very hard problem.
#+begin_src scheme :exports both :results output
  (define (square-tree tree) (tree-map square tree))

  (define (tree-map square tree)
    (map (lambda (sub-tree)
	   (if (pair? sub-tree)
	       (tree-map square sub-tree)
	       (square sub-tree)))
	 tree))
  (show #t " " 
	(square-tree
	 (list 1
	       (list 2 (list 3 4) 5)
	       (list 6 7))))

#+end_src

#+RESULTS:
:  (1 (4 (9 16) 25) (36 49))

*** DONE Exercise 2.32 subsets
    CLOSED: [2019-09-11 Wed 14:53]

#+begin_src scheme :exports both :results value :noweb-ref subsets
  (define (subsets s)
    (if (null? s)
	(list '())
	(let ((rest (subsets (cdr s))))
	  (append rest (map (lambda (suffix) (append (list (car s)) suffix)) rest)))))
  (subsets '(1 2 3))
#+end_src

#+RESULTS:
|---+---+---|
| 3 |   |   |
| 2 |   |   |
| 2 | 3 |   |
| 1 |   |   |
| 1 | 3 |   |
| 1 | 2 |   |
| 1 | 2 | 3 |

The explanation is easy. The subsets can be constructed by taking any
element, say, the first, and appending it to every subset of the rest
of the set. That is if we already have a set of subsets of some set
*S*, and we are adding some element *a*, then it may or may not be in
every subset of the enlarged set *S+a*. 

*** TODO Figure 2.7 Signal-flow diagram

*** DONE Exercise 2.33 map-append-length
    CLOSED: [2019-09-11 Wed 23:53]

#+begin_src scheme :exports both :results value :noweb-ref filter
  (define (filter predicate sequence)
    (cond ((null? sequence) '())
	  ((predicate (car sequence))
	   (cons (car sequence)
		 (filter predicate (cdr sequence))))
	  (else (filter predicate (cdr sequence)))))
#+end_src
n
#+begin_src scheme :exports both :results value :noweb-ref accumulate
  (define (accumulate op initial sequence)
    (if (null? sequence)
	initial
	    (accumulate op (op initial (car sequence)) (cdr sequence))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref enumerate-interval
  (define (enumerate-interval low high)
    (if (> low high)
	'()
	(cons low (enumerate-interval (+ low 1) high))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref enumerate-tree
  (define (enumerate-tree tree)
    (cond ((null? tree) '())
	   ((not (pair? tree)) (list tree))
	   (else (append (enumerate-tree (car tree))
			 (enumerate-tree (cdr tree))))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref map-append-length
  (define (map p sequence)
    (accumulate (lambda (x y) (x y)) '() sequence))
  (define (append seq1 seq2)
    (accumulate cons seq2 seq1))
  (define (length sequence)
    (accumulate (lambda (x y) (+ 1 y))))
#+end_src

#+begin_src scheme :exports both :results value
 (length (make-list 100 99))
#+end_src

#+RESULTS:
: 100

*** DONE Exercise 2.34 horners-rule
    CLOSED: [2019-09-12 Thu 00:01]
#+begin_src scheme :exports both :results value
<<accumulate>>
  (define (horner-eval x coefficient-sequence)
    (accumulate (lambda (this-coeff higher-terms) (+ this-coeff (* x higher-terms)))
		0
		coefficient-sequence))
  (horner-eval 2 (list 1 3 0 5 0 1))

#+end_src

#+RESULTS:
: 79

*** DONE Exercise 2.35 count-leaves-accumulate
    CLOSED: [2019-09-12 Thu 00:17]
#+begin_src scheme :exports both :results value
<<accumulate>>
  (define (count-leaves t)
    (accumulate + 0 (map (lambda (x) (if (pair? x)
				    (count-leaves x)
				    1)) t)))
  (count-leaves (list 1 2 3))
#+end_src

#+RESULTS:
: 3

*** DONE Exercise 2.36 accumulate-n
    CLOSED: [2019-09-12 Thu 00:26]
#+begin_src scheme :exports both :results value :noweb-ref accumulate-n
<<accumulate>>
  (define (accumulate-n op init seqs)
    (if (null? (car seqs))
	'()
	(cons (accumulate op init (map car seqs))
              (accumulate-n op init (map cdr seqs)))))
#+end_src
  
#+begin_src scheme :exports both :results value
<<accumulate-n>>
  (accumulate-n + 0 '((1 2 3) (4 5 6) (7 8 9) (10 11 12)))
#+end_src

#+RESULTS:
| 22 | 26 | 30 |

*** DONE Exercise 2.37 matrix-*-vector
    CLOSED: [2019-09-12 Thu 00:50]

#+begin_src scheme :exports both :results value :noweb-ref dot-product
  (define (dot-product v w)
    (accumulate + 0 (map * v w)))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref matrix-operations
  (define (matrix-*-vector m v)
    (map (lambda (x) (dot-product v x)) m))
  (define (transpose mat)
    (accumulate-n cons '() mat))
  (define (matrix-*-matrix m n)
    (let ((cols (transpose n)))
      (map (lambda (x) (matrix-*-vector m x)) n)))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<accumulate>>
<<accumulate-n>>
<<dot-product>>
<<matrix-operations>>
(show #t " " (matrix-*-vector '((1 2 3 4) (4 5 6 6) (6 7 8 9)) '(1 2 3 4)) "\n")
(show #t " " (transpose '((1 2 3 4) (4 5 6 6) (6 7 8 9))) "\n")
(show #t " " (matrix-*-matrix
               '((1 2 3 4) (4 5 6 6) (6 7 8 9)) 
               '((1 2 3 4) (4 5 6 6) (6 7 8 9)) ) "\n")
#+end_src

#+RESULTS:
:  (30 56 80)
:  ((1 4 6) (2 5 7) (3 6 8) (4 6 9))
:  ((30 56 80) (56 113 161) (80 161 230))

*** DONE Exercise 2.38 fold-left
    CLOSED: [2019-09-12 Thu 09:45]
#+begin_src scheme :exports both :results value :noweb-ref fold-left
  (define (fold-left op initial sequence)
    (define (iter result rest)
      (if (null? rest)
	  result
	  (iter (op result (car rest))
		(cdr rest))))
    (iter initial sequence))
#+end_src

#+begin_src scheme :exports both :results output
<<accumulate>>
<<fold-left>>
(show #t " " (accumulate / 1 (list 1 2 3)) "\n")
(show #t " " (fold-left / 1 (list 1 2 3)) "\n")
(show #t " " (accumulate list '() (list 1 2 3)) "\n")
(show #t " " (fold-left list '() (list 1 2 3)) "\n")
(show #t " " (fold-left + 0 (list 1 2 3)) "\n")
(show #t " " (accumulate + 0 (list 1 2 3)) "\n")
#+end_src

#+RESULTS:
:  3/2
:  1/6
:  (1 (2 (3 ())))
:  (((() 1) 2) 3)
:  6
:  6

Well, it seems that commutative operations, that is the ones for which
\(a+b = b+a\).

*** DONE Exercise 2.39 reverse fold-right fold-left
    CLOSED: [2019-09-12 Thu 09:52]

#+begin_src scheme :exports both :results output
<<accumulate>>
<<fold-left>>
  (define (reverse sequence)
    (accumulate (lambda (x y) (cons x y)) '() sequence))
  (show #t " " (reverse (list 1 2 3)) "\n")
  (define (reverse sequence)
    (fold-left  (lambda (x y) (cons y x)) '() sequence))
  (show #t " " (reverse (list 1 2 3)))

#+end_src

#+RESULTS:
:  (1 2 3)
:  (3 2 1)

*** DONE Exercise 2.40 unique-pairs
    CLOSED: [2019-09-12 Thu 10:34]
0:42:00

#+begin_src scheme :exports both :results value :noweb-ref flatmap
  (define (flatmap proc seq)
    (accumulate append '() (map proc seq)))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref prime-sum
  (define (prime-sum? pair)
    (prime? (+ (car pair) (cadr pair))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref make-pair-sum
(define (make-pair-sum pair)
    (list (car pair) (cadr pair) (+ (car pair) (cadr pair))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref prime-sum-pairs
  (define (prime-sum-pairs n)
    (map make-pair-sum
	  (filter prime-sum? (flatmap
			      (lambda (i)
				(map (lambda (j) (list i j))
				     (enumerate-interval 1 (- i 1))))
			      (enumerate-interval 1 n)))))
#+end_src

#+begin_src scheme :exports both :results output
<<prime-sum-pairs>>
<<enumerate-interval>>
<<flatmap>>
<<accumulate>>
<<prime-sum>>
<<filter>>
<<fast-prime>>
<<fermat-primetest>>
<<expmod-miller-rabin>>
<<make-pair-sum>>
<<map-append-length>>
(show #t " " (prime-sum-pairs 30))
#+end_src

#+RESULTS:
:  ((2 1 3) (3 2 5) (4 1 5) (4 3 7) (5 2 7) (6 1 7) (6 5 11) (7 4 11) (7 6 13) (8 3 11) (8 5 13) (9 2 11) (9 4 13) (9 8 17) (10 1 11) (10 3 13) (10 7 17) (10 9 19) (11 2 13) (11 6 17) (11 8 19) (12 1 13) (12 5 17) (12 7 19) (12 11 23) (13 4 17) (13 6 19) (13 10 23) (14 3 17) (14 5 19) (14 9 23) (15 2 17) (15 4 19) (15 8 23) (15 14 29) (16 1 17) (16 3 19) (16 7 23) (16 13 29) (16 15 31) (17 2 19) (17 6 23) (17 12 29) (17 14 31) (18 1 19) (18 5 23) (18 11 29) (18 13 31) (19 4 23) (19 10 29) (19 12 31) (19 18 37) (20 3 23) (20 9 29) (20 11 31) (20 17 37) (21 2 23) (21 8 29) (21 10 31) (21 16 37) (21 20 41) (22 1 23) (22 7 29) (22 9 31) (22 15 37) (22 19 41) (22 21 43) (23 6 29) (23 8 31) (23 14 37) (23 18 41) (23 20 43) (24 5 29) (24 7 31) (24 13 37) (24 17 41) (24 19 43) (24 23 47) (25 4 29) (25 6 31) (25 12 37) (25 16 41) (25 18 43) (25 22 47) (26 3 29) (26 5 31) (26 11 37) (26 15 41) (26 17 43) (26 21 47) (27 2 29) (27 4 31) (27 10 37) (27 14 41) (27 16 43) (27 20 47) (27 26 53) (28 1 29) (28 3 31) (28 9 37) (28 13 41) (28 15 43) (28 19 47) (28 25 53) (29 2 31) (29 8 37) (29 12 41) (29 14 43) (29 18 47) (29 24 53) (30 1 31) (30 7 37) (30 11 41) (30 13 43) (30 17 47) (30 23 53) (30 29 59))

#+begin_src scheme :exports both :results value :noweb-ref unique-pairs
  (define (unique-pairs n)
    (flatmap
     (lambda (i)
       (map (lambda (j) (list i j))
	    (enumerate-interval 1 (- i 1))))
     (enumerate-interval 1 n)))
#+end_src

#+begin_src scheme :exports both :results value
  <<unique-pairs>>
  <<flatmap>>
  <<enumerate-interval>>
  <<accumulate>>
  (unique-pairs 3)
#+end_src

#+RESULTS:
| 2 | 1 |
| 3 | 1 |
| 3 | 2 |

#+begin_src scheme :exports both :results value :noweb-ref prime-sum-pairs-unique-pairs
  (define (prime-sum-pairs n)
    (map make-pair-sum
	  (filter prime-sum? (unique-pairs n))))
#+end_src

#+begin_src scheme :exports both :results value
<<unique-pairs>>
<<prime-sum-pairs-unique-pairs>>
<<enumerate-interval>>
<<flatmap>>
<<accumulate>>
<<prime-sum>>
<<filter>>
<<fast-prime>>
<<fermat-primetest>>
<<expmod-miller-rabin>>
<<make-pair-sum>>
<<map-append-length>>
(prime-sum-pairs 10)
#+end_src

#+RESULTS:
|  2 | 1 |  3 |
|  3 | 2 |  5 |
|  4 | 1 |  5 |
|  4 | 3 |  7 |
|  5 | 2 |  7 |
|  6 | 1 |  7 |
|  6 | 5 | 11 |
|  7 | 4 | 11 |
|  7 | 6 | 13 |
|  8 | 3 | 11 |
|  8 | 5 | 13 |
|  9 | 2 | 11 |
|  9 | 4 | 13 |
|  9 | 8 | 17 |
| 10 | 1 | 11 |
| 10 | 3 | 13 |
| 10 | 7 | 17 |
| 10 | 9 | 19 |

I have to note that this deceiptively simple task involves reusing
results of 12 other problems.
 
*** DONE Exercise 2.41 triple-sum
    CLOSED: [2019-09-14 Sat 15:15]
     *Exercise 2.41:* Write a procedure to find all ordered triples of
     distinct positive integers i, j, and k less than or equal to a
     given integer n that sum to a given integer s.

#+begin_src scheme :exports both :results value :noweb-ref unique-triples
    (define (unique-triples n)
      (flatmap
       (lambda (i)
	 (flatmap (lambda (j) 
		(map (lambda (k) (list i j k))
		     (enumerate-interval 1 (- j 1))))
	      (enumerate-interval 1 (- i 1))))
       (enumerate-interval 1 n)))

#+end_src

#+begin_src scheme :exports both :results output
<<accumulate>>
<<enumerate-interval>>
<<flatmap>>
<<unique-triples>>
(show #t " " (unique-triples 5) "\n")
#+end_src

#+RESULTS:
:  ((3 2 1) (4 2 1) (4 3 1) (4 3 2) (5 2 1) (5 3 1) (5 3 2) (5 4 1) (5 4 2) (5 4 3))



#+begin_src scheme :exports both :results value :noweb-ref sum-equal-s
  (define (sum-equal-s? s tuple)
    (if (= s  (accumulate + 0 tuple))
	#t
	#f))
#+end_src

#+begin_src scheme :exports both :results value
<<sum-equal-s>>
<<accumulate>>
(and (sum-equal-s? 30 (list 10 5 5 9 1)) (not (sum-equal-s? 10 (list 3 3 3))))
#+end_src

#+RESULTS:
: #t

#+begin_src scheme :exports both :results value :noweb-ref sum-equal-s-triples
  (define (sum-equal-s-triples s n)
    (filter (lambda (x) (sum-equal-s? s x)) (unique-triples n)))
#+end_src

#+begin_src scheme :exports both :results value
<<enumerate-interval>>
<<flatmap>>
<<sum-equal-s-triples>>
<<accumulate>>
<<sum-equal-s>>
<<filter>>
<<unique-triples>>
(sum-equal-s-triples 15 30)
#+end_src

#+RESULTS:
|  6 | 5 | 4 |
|  7 | 5 | 3 |
|  7 | 6 | 2 |
|  8 | 4 | 3 |
|  8 | 5 | 2 |
|  8 | 6 | 1 |
|  9 | 4 | 2 |
|  9 | 5 | 1 |
| 10 | 3 | 2 |
| 10 | 4 | 1 |
| 11 | 3 | 1 |
| 12 | 2 | 1 |

*** DONE Figure 2.8 A solution to the eight-queens puzzle.

#+begin_src plantuml :exports both :file figure-2-8.png
@startditaa
          +---+---+---+---+---+---+---+---+
          |   |   |   |   |   | Q |   |   |
          +---+---+---+---+---+---+---+---+
          |   |   | Q |   |   |   |   |   |
          +---+---+---+---+---+---+---+---+
          | Q |   |   |   |   |   |   |   |
          +---+---+---+---+---+---+---+---+
          |   |   |   |   |   |   | Q |   |
          +---+---+---+---+---+---+---+---+
          |   |   |   |   | Q |   |   |   |
          +---+---+---+---+---+---+---+---+
          |   |   |   |   |   |   |   | Q |
          +---+---+---+---+---+---+---+---+
          |   | Q |   |   |   |   |   |   |
          +---+---+---+---+---+---+---+---+
          |   |   |   | Q |   |   |   |   |
          +---+---+---+---+---+---+---+---+
@endditaa
#+end_src 

#+RESULTS:
[[file:figure-2-8.png]]

*** DONE Exercise 2.42 k-queens
    CLOSED: [2019-09-17 Tue 22:27]
3:00:00 + 2:00:00 + 1:00:00 = 6:00:00
The commentary to this problem is bad. Firstly, it is *NOT* obvious
that it is even possible to place a queen into every column and every
row. Indeed, in the solution above, this happens to be the case, but
this is by no means obvious.

The second thought: since the algorithm is expected to provide *all*
possible solutions, it should be required have a list of lists... sort
of, to represent the multitude. So ~queens~ should return a list of
lists. 

Secondly, the code given by the authors is totally moronic in at least
two places: 
 1. rest-of-queens? Seriously? Why not "world of queens", or
    "suffix-queens", to make it even more obscure? It should have been
    called "prefix-queens", or, better "queens-already-on-board". We
    are not short of bytes, are we?
 2. who on Earth would call a procedure "queen-cols"? What does it
even mean? Descriptive names -- zero.
 
The third thought: anyone who wants to solve this puzzle, must at
least know what it is for a queen to be "safe". That is, if a queen
number A has a position b_1 then our new queen's B position b_2 must
satisfy : 1) b_2 \neq b_1 2)|b_2 - b_1| \ne B - A. And this must be true
\forall A < B.

The fourth thought: it is *NOT* obvious, but the "rest of queens"
contains the list of queens _in the reversed order_. So ~car~'ing
anything with it represents attaching the queen _to the end_ of the
list. This is why we have *k* supplied as an argument to the ~safe?~
procedure.

#+begin_src scheme :exports both :results value :noweb-ref k-queens
  (define (queens board-size)
    (define (queen-cols k)
      (if (= k 0)
	  (list empty-board)
	  (filter
	   (lambda (positions) (safe? k positions))
	   (flatmap
	    (lambda (rest-of-queens)
	      (map (lambda (new-row)
		     (adjoin-position new-row k rest-of-queens))
		   (enumerate-interval 1 board-size)))
	    (queen-cols (- k 1))))))
    (queen-cols board-size))

#+end_src

#+begin_src scheme :exports both :results output
<<k-queens>>
<<flatmap>>
<<enumerate-interval>>
<<accumulate>>
<<filter>>
  (define empty-board '())
  (define (adjoin-position new-row k rest-of-queens)
    (cons (cons k new-row) rest-of-queens))
  (define (safe? k positions)
    (cond ((null? (cdr positions)) #t)
	  ((= k 1) #t)
	  ((= (cdar positions) (cdadr positions)) #f)
	  ((= (abs (- (cdar positions) (cdadr positions))) (abs (- (caar positions) (caadr positions)))) #f)
	  (else (safe? k (cons (car positions) (cddr positions))))))
(map (lambda (x) (show #t " " x "\n")) (queens 8))
#+end_src

#+RESULTS:
#+begin_example
 ((8 . 4) (7 . 2) (6 . 7) (5 . 3) (4 . 6) (3 . 8) (2 . 5) (1 . 1))
 ((8 . 5) (7 . 2) (6 . 4) (5 . 7) (4 . 3) (3 . 8) (2 . 6) (1 . 1))
 ((8 . 3) (7 . 5) (6 . 2) (5 . 8) (4 . 6) (3 . 4) (2 . 7) (1 . 1))
 ((8 . 3) (7 . 6) (6 . 4) (5 . 2) (4 . 8) (3 . 5) (2 . 7) (1 . 1))
 ((8 . 5) (7 . 7) (6 . 1) (5 . 3) (4 . 8) (3 . 6) (2 . 4) (1 . 2))
 ((8 . 4) (7 . 6) (6 . 8) (5 . 3) (4 . 1) (3 . 7) (2 . 5) (1 . 2))
 ((8 . 3) (7 . 6) (6 . 8) (5 . 1) (4 . 4) (3 . 7) (2 . 5) (1 . 2))
 ((8 . 5) (7 . 3) (6 . 8) (5 . 4) (4 . 7) (3 . 1) (2 . 6) (1 . 2))
 ((8 . 5) (7 . 7) (6 . 4) (5 . 1) (4 . 3) (3 . 8) (2 . 6) (1 . 2))
 ((8 . 4) (7 . 1) (6 . 5) (5 . 8) (4 . 6) (3 . 3) (2 . 7) (1 . 2))
 ((8 . 3) (7 . 6) (6 . 4) (5 . 1) (4 . 8) (3 . 5) (2 . 7) (1 . 2))
 ((8 . 4) (7 . 7) (6 . 5) (5 . 3) (4 . 1) (3 . 6) (2 . 8) (1 . 2))
 ((8 . 6) (7 . 4) (6 . 2) (5 . 8) (4 . 5) (3 . 7) (2 . 1) (1 . 3))
 ((8 . 6) (7 . 4) (6 . 7) (5 . 1) (4 . 8) (3 . 2) (2 . 5) (1 . 3))
 ((8 . 1) (7 . 7) (6 . 4) (5 . 6) (4 . 8) (3 . 2) (2 . 5) (1 . 3))
 ((8 . 6) (7 . 8) (6 . 2) (5 . 4) (4 . 1) (3 . 7) (2 . 5) (1 . 3))
 ((8 . 6) (7 . 2) (6 . 7) (5 . 1) (4 . 4) (3 . 8) (2 . 5) (1 . 3))
 ((8 . 4) (7 . 7) (6 . 1) (5 . 8) (4 . 5) (3 . 2) (2 . 6) (1 . 3))
 ((8 . 5) (7 . 8) (6 . 4) (5 . 1) (4 . 7) (3 . 2) (2 . 6) (1 . 3))
 ((8 . 4) (7 . 8) (6 . 1) (5 . 5) (4 . 7) (3 . 2) (2 . 6) (1 . 3))
 ((8 . 2) (7 . 7) (6 . 5) (5 . 8) (4 . 1) (3 . 4) (2 . 6) (1 . 3))
 ((8 . 1) (7 . 7) (6 . 5) (5 . 8) (4 . 2) (3 . 4) (2 . 6) (1 . 3))
 ((8 . 2) (7 . 5) (6 . 7) (5 . 4) (4 . 1) (3 . 8) (2 . 6) (1 . 3))
 ((8 . 4) (7 . 2) (6 . 7) (5 . 5) (4 . 1) (3 . 8) (2 . 6) (1 . 3))
 ((8 . 5) (7 . 7) (6 . 1) (5 . 4) (4 . 2) (3 . 8) (2 . 6) (1 . 3))
 ((8 . 6) (7 . 4) (6 . 1) (5 . 5) (4 . 8) (3 . 2) (2 . 7) (1 . 3))
 ((8 . 5) (7 . 1) (6 . 4) (5 . 6) (4 . 8) (3 . 2) (2 . 7) (1 . 3))
 ((8 . 5) (7 . 2) (6 . 6) (5 . 1) (4 . 7) (3 . 4) (2 . 8) (1 . 3))
 ((8 . 6) (7 . 3) (6 . 7) (5 . 2) (4 . 8) (3 . 5) (2 . 1) (1 . 4))
 ((8 . 2) (7 . 7) (6 . 3) (5 . 6) (4 . 8) (3 . 5) (2 . 1) (1 . 4))
 ((8 . 7) (7 . 3) (6 . 1) (5 . 6) (4 . 8) (3 . 5) (2 . 2) (1 . 4))
 ((8 . 5) (7 . 1) (6 . 8) (5 . 6) (4 . 3) (3 . 7) (2 . 2) (1 . 4))
 ((8 . 1) (7 . 5) (6 . 8) (5 . 6) (4 . 3) (3 . 7) (2 . 2) (1 . 4))
 ((8 . 3) (7 . 6) (6 . 8) (5 . 1) (4 . 5) (3 . 7) (2 . 2) (1 . 4))
 ((8 . 6) (7 . 3) (6 . 1) (5 . 7) (4 . 5) (3 . 8) (2 . 2) (1 . 4))
 ((8 . 7) (7 . 5) (6 . 3) (5 . 1) (4 . 6) (3 . 8) (2 . 2) (1 . 4))
 ((8 . 7) (7 . 3) (6 . 8) (5 . 2) (4 . 5) (3 . 1) (2 . 6) (1 . 4))
 ((8 . 5) (7 . 3) (6 . 1) (5 . 7) (4 . 2) (3 . 8) (2 . 6) (1 . 4))
 ((8 . 2) (7 . 5) (6 . 7) (5 . 1) (4 . 3) (3 . 8) (2 . 6) (1 . 4))
 ((8 . 3) (7 . 6) (6 . 2) (5 . 5) (4 . 8) (3 . 1) (2 . 7) (1 . 4))
 ((8 . 6) (7 . 1) (6 . 5) (5 . 2) (4 . 8) (3 . 3) (2 . 7) (1 . 4))
 ((8 . 8) (7 . 3) (6 . 1) (5 . 6) (4 . 2) (3 . 5) (2 . 7) (1 . 4))
 ((8 . 2) (7 . 8) (6 . 6) (5 . 1) (4 . 3) (3 . 5) (2 . 7) (1 . 4))
 ((8 . 5) (7 . 7) (6 . 2) (5 . 6) (4 . 3) (3 . 1) (2 . 8) (1 . 4))
 ((8 . 3) (7 . 6) (6 . 2) (5 . 7) (4 . 5) (3 . 1) (2 . 8) (1 . 4))
 ((8 . 6) (7 . 2) (6 . 7) (5 . 1) (4 . 3) (3 . 5) (2 . 8) (1 . 4))
 ((8 . 3) (7 . 7) (6 . 2) (5 . 8) (4 . 6) (3 . 4) (2 . 1) (1 . 5))
 ((8 . 6) (7 . 3) (6 . 7) (5 . 2) (4 . 4) (3 . 8) (2 . 1) (1 . 5))
 ((8 . 4) (7 . 2) (6 . 7) (5 . 3) (4 . 6) (3 . 8) (2 . 1) (1 . 5))
 ((8 . 7) (7 . 1) (6 . 3) (5 . 8) (4 . 6) (3 . 4) (2 . 2) (1 . 5))
 ((8 . 1) (7 . 6) (6 . 8) (5 . 3) (4 . 7) (3 . 4) (2 . 2) (1 . 5))
 ((8 . 3) (7 . 8) (6 . 4) (5 . 7) (4 . 1) (3 . 6) (2 . 2) (1 . 5))
 ((8 . 6) (7 . 3) (6 . 7) (5 . 4) (4 . 1) (3 . 8) (2 . 2) (1 . 5))
 ((8 . 7) (7 . 4) (6 . 2) (5 . 8) (4 . 6) (3 . 1) (2 . 3) (1 . 5))
 ((8 . 4) (7 . 6) (6 . 8) (5 . 2) (4 . 7) (3 . 1) (2 . 3) (1 . 5))
 ((8 . 2) (7 . 6) (6 . 1) (5 . 7) (4 . 4) (3 . 8) (2 . 3) (1 . 5))
 ((8 . 2) (7 . 4) (6 . 6) (5 . 8) (4 . 3) (3 . 1) (2 . 7) (1 . 5))
 ((8 . 3) (7 . 6) (6 . 8) (5 . 2) (4 . 4) (3 . 1) (2 . 7) (1 . 5))
 ((8 . 6) (7 . 3) (6 . 1) (5 . 8) (4 . 4) (3 . 2) (2 . 7) (1 . 5))
 ((8 . 8) (7 . 4) (6 . 1) (5 . 3) (4 . 6) (3 . 2) (2 . 7) (1 . 5))
 ((8 . 4) (7 . 8) (6 . 1) (5 . 3) (4 . 6) (3 . 2) (2 . 7) (1 . 5))
 ((8 . 2) (7 . 6) (6 . 8) (5 . 3) (4 . 1) (3 . 4) (2 . 7) (1 . 5))
 ((8 . 7) (7 . 2) (6 . 6) (5 . 3) (4 . 1) (3 . 4) (2 . 8) (1 . 5))
 ((8 . 3) (7 . 6) (6 . 2) (5 . 7) (4 . 1) (3 . 4) (2 . 8) (1 . 5))
 ((8 . 4) (7 . 7) (6 . 3) (5 . 8) (4 . 2) (3 . 5) (2 . 1) (1 . 6))
 ((8 . 4) (7 . 8) (6 . 5) (5 . 3) (4 . 1) (3 . 7) (2 . 2) (1 . 6))
 ((8 . 3) (7 . 5) (6 . 8) (5 . 4) (4 . 1) (3 . 7) (2 . 2) (1 . 6))
 ((8 . 4) (7 . 2) (6 . 8) (5 . 5) (4 . 7) (3 . 1) (2 . 3) (1 . 6))
 ((8 . 5) (7 . 7) (6 . 2) (5 . 4) (4 . 8) (3 . 1) (2 . 3) (1 . 6))
 ((8 . 7) (7 . 4) (6 . 2) (5 . 5) (4 . 8) (3 . 1) (2 . 3) (1 . 6))
 ((8 . 8) (7 . 2) (6 . 4) (5 . 1) (4 . 7) (3 . 5) (2 . 3) (1 . 6))
 ((8 . 7) (7 . 2) (6 . 4) (5 . 1) (4 . 8) (3 . 5) (2 . 3) (1 . 6))
 ((8 . 5) (7 . 1) (6 . 8) (5 . 4) (4 . 2) (3 . 7) (2 . 3) (1 . 6))
 ((8 . 4) (7 . 1) (6 . 5) (5 . 8) (4 . 2) (3 . 7) (2 . 3) (1 . 6))
 ((8 . 5) (7 . 2) (6 . 8) (5 . 1) (4 . 4) (3 . 7) (2 . 3) (1 . 6))
 ((8 . 3) (7 . 7) (6 . 2) (5 . 8) (4 . 5) (3 . 1) (2 . 4) (1 . 6))
 ((8 . 3) (7 . 1) (6 . 7) (5 . 5) (4 . 8) (3 . 2) (2 . 4) (1 . 6))
 ((8 . 8) (7 . 2) (6 . 5) (5 . 3) (4 . 1) (3 . 7) (2 . 4) (1 . 6))
 ((8 . 3) (7 . 5) (6 . 2) (5 . 8) (4 . 1) (3 . 7) (2 . 4) (1 . 6))
 ((8 . 3) (7 . 5) (6 . 7) (5 . 1) (4 . 4) (3 . 2) (2 . 8) (1 . 6))
 ((8 . 5) (7 . 2) (6 . 4) (5 . 6) (4 . 8) (3 . 3) (2 . 1) (1 . 7))
 ((8 . 6) (7 . 3) (6 . 5) (5 . 8) (4 . 1) (3 . 4) (2 . 2) (1 . 7))
 ((8 . 5) (7 . 8) (6 . 4) (5 . 1) (4 . 3) (3 . 6) (2 . 2) (1 . 7))
 ((8 . 4) (7 . 2) (6 . 5) (5 . 8) (4 . 6) (3 . 1) (2 . 3) (1 . 7))
 ((8 . 4) (7 . 6) (6 . 1) (5 . 5) (4 . 2) (3 . 8) (2 . 3) (1 . 7))
 ((8 . 6) (7 . 3) (6 . 1) (5 . 8) (4 . 5) (3 . 2) (2 . 4) (1 . 7))
 ((8 . 5) (7 . 3) (6 . 1) (5 . 6) (4 . 8) (3 . 2) (2 . 4) (1 . 7))
 ((8 . 4) (7 . 2) (6 . 8) (5 . 6) (4 . 1) (3 . 3) (2 . 5) (1 . 7))
 ((8 . 6) (7 . 3) (6 . 5) (5 . 7) (4 . 1) (3 . 4) (2 . 2) (1 . 8))
 ((8 . 6) (7 . 4) (6 . 7) (5 . 1) (4 . 3) (3 . 5) (2 . 2) (1 . 8))
 ((8 . 4) (7 . 7) (6 . 5) (5 . 2) (4 . 6) (3 . 1) (2 . 3) (1 . 8))
 ((8 . 5) (7 . 7) (6 . 2) (5 . 6) (4 . 3) (3 . 1) (2 . 4) (1 . 8))
#+end_example

Because of really terrible introduction, this exercise took me 6 times
more than it's worth.

*** DONE Exercise 2.43 slow k-queens
    CLOSED: [2019-09-17 Tue 22:55]

To answer this exercise, we need to estimate the complexity of the
canonical solution and Louis' solution.

For the canonical solution, we can safely assume that the ~safe?~
procedure filters out no sequences at all (this would only worsen our
estimate). Therefore, every additional column would multiply the total
computation needed by the size of the column. Roughly speaking, this
would be \(k^k \approx 2^k \rightarrow 2^{}^6 = 64\).

For the Louis's solution, however, the ~(queen-cols (- k 1))~ is
solved for every value of ~k~ from scratch, which is not necessary,
and adds an additional multiplicand of \(k^{k-1}\) for every
~k~. Roughly speaking, this adds an additional power of \(k-1\) to the
solution time. \( (k\cdot T)^k \approx 2^{6k}\rightarrow 2^{36}\). A little bit too much.

*** Remark. Now we are starting the "picture language" chapter. 
It may (and will) require extensive modification to the standard
working environment, because I am not using the most default nowadays
Racket. In this subsection I will implement the required subroutines.

SICP is incredibly confusing in this chapter. 

The following is one of the most prominent examples:
#+begin_src scheme :exports both :results value
(define (segments->painter segment-list)
       (lambda (frame)
         (for-each
          (lambda (segment)
            (draw-line
             ((frame-coord-map frame) (start-segment segment))
             ((frame-coord-map frame) (end-segment segment))))
          segment-list)))
#+end_src

#+begin_src scheme :exports both :results output :noweb-ref draw-line
  (define canvas-size
    (make-parameter
     200
     (lambda (size)
       (if (and (exact-integer? size) (<= 2 size 1000))
	   size
	   (error "invalid canvas size")))))
  (define canvas-file-name
     (make-parameter
        (string-append "./" (substring (process->string "uuidgen") 0 36) ".png")
	(lambda (name)
	  (if (string? name)
	      name
	      (error "invalid canvas file name")))))
  (define (canvas-reset)
    (system "rm" (canvas-file-name))
    (system "convert" "xc:white"
	    "-scale" (string-append
		      (number->string (canvas-size))
		      "x"
		      (number->string (canvas-size)))
	    (canvas-file-name)))
  (define (canvas-refresh)
    (string-append "[[" (canvas-file-name) "]]"))
  (canvas-reset)
  (define (draw-line point1 point2)
    (system "mogrify"
	    "-fill" "black"
	    "-draw" (string-append "line "
				   (number->string (* (canvas-size) (car point1)))
				   ","
				   (number->string (* (canvas-size) (cadr point1)))
				   " "
				   (number->string (* (canvas-size) (car point2)))
				   ","
				   (number->string (* (canvas-size) (cadr point2))))
	    (canvas-file-name))
    #;(display (string-append "[[" (canvas-file-name) "]]"))
    (string-append "[[" (canvas-file-name) "]]"))
#+end_src

#+RESULTS:


#+begin_src scheme :exports both :results raw value
  <<draw-line>>
  (draw-line (list 0 0) (list 1 1))
  (draw-line (list 0 1) (list 1 0))
#+end_src

#+RESULTS:
[[./d890f987-3ba1-41f4-a2b2-c427aa7c2858.gif]]

#+begin_src scheme :exports both :results value :noweb-ref pict-frame
  (define (frame-coord-map frame)
    (lambda (v)
     (add-vect
       (origin-frame frame)
              (add-vect (scale-vect (xcor-vect v) (edge1-frame frame))
		 (scale-vect (ycor-vect v) (edge2-frame frame))))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value
  <<make-frame>>
  <<pict-frame>>
  <<pict-vect>>
  ((frame-coord-map
	   (make-frame
	    (make-vect 0.1 0.2)
	    (make-vect 1.0 1.0)
	    (make-vect 1.0 1.0))) (make-vect 0 0))
#+end_src

#+RESULTS:
| 0.1 | 0.2 |

#+begin_src scheme :exports both :results raw value :noweb-ref segments-painter
  (define (segments->painter segment-list)
    (lambda (frame)
      (for-each
       (lambda (segment)
	 (draw-line
	  ((frame-coord-map frame)
	   (start-segment segment))
	  ((frame-coord-map frame)
	   (end-segment segment))))
       segment-list)))
#+end_src

The next is the "rogers" painter. As usual with SICP, fighting with
the programming system takes more time than actually solving anything.
Took me 3 hours. (3:00:00)

Asked a question here: https://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=36770


#+begin_src scheme :exports both :results value :noweb-ref magick-vect
    (define (pict-vect->magick-vect vector separator)
      (string-append
       (number->string (+ 1 (* (canvas-size) (xcor-vect vector))))
       separator
       (number->string (+ 1 (* (canvas-size) (ycor-vect vector))))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref rogers
  (define (rogers frame)
    (system "convert" 
             (canvas-file-name)
             "("
	     "+distort" "affine"
	     (string-append 
		"1,1 "    "1,1"
		" 149,1 "   (pict-vect->magick-vect (edge1-frame  frame) ",")
                " 1,180 "  (pict-vect->magick-vect (edge2-frame  frame) ","))
             "-background" "transparent"
	     "-splice" (pict-vect->magick-vect
			(origin-frame frame) "x")
             "./assets/rogers.png" ")" 
             "-composite"            
             (canvas-file-name)))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results raw value
<<pict-vect>>
<<pict-frame>>
<<make-frame>>
<<magick-vect>>
<<rogers>>
<<draw-line>>
(rogers (make-frame (make-vect 0 0) (make-vect 1 0) (make-vect 0 1)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./755096f1-280f-4e39-bd9f-c17dada9ed69.png]]

#+begin_src scheme :exports both :results value :noweb-ref wave-bitmap
  (define (wave frame)
    #;(convert white.gif \( -distort "Affine" "1,1 1,1  1,149 1,200  180,1 200,1"  rogers.png \) -composite  output.gif)
    #;(convert rogers.png  -alpha set -virtual-pixel transparent +distort affine "1,1 1,1 1,50 1,50 50,1 50,50" -background transparent -splice "50x50" output.png)
    (system "convert" 
	     (canvas-file-name)
	     "("
	     "-alpha" "set" "-virtual-pixel" "transparent"
	     "+distort" "affine"
	     (string-append 
		"1,1 "    "1,1"
		" 152,1 "   (pict-vect->magick-vect
			      (edge1-frame  frame) ",")
		" 1,184 "   (pict-vect->magick-vect
			      (edge2-frame  frame) ","))
	     "-background" "transparent"
	     "-splice" (pict-vect->magick-vect
			(origin-frame frame) "x")
	     "./assets/wave.png" ")"
	     "-composite"
	     (canvas-file-name)))
#+end_src

#+RESULTS:
: #<undef>

*** DONE Exercise 2.44 up-split
    CLOSED: [2019-09-23 Mon 22:54]

#+begin_src scheme :exports both :results value :noweb-ref up-split
  (define (up-split painter n)
    (if (= n 0)
	painter
	(let ((smaller (up-split painter (- n 1))))
	  (below painter (beside smaller smaller)))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results raw value
<<pict-vect>>
<<make-frame>>
<<pict-segment>>
<<segments-painter>>
<<wave-segment>>
<<transform-painter>>
<<pict-frame>>
<<draw-line>>
<<beside>>
<<below-beside>>
<<rotate270>>
<<rotate90>>
<<up-split>>
((up-split wave 1) (make-frame (make-vect 0.0 1.0) (make-vect 1.0 0.0) (make-vect 0.0 -1.0)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./47ef240d-2a8b-4886-8431-c7aade49fb09.png]]

*** DONE Exercise 2.45 split
    CLOSED: [2019-09-24 Tue 01:37]

#+begin_src scheme :exports both :results value :noweb-ref split
  (define (split op1 op2)
    (define (split-inner painter n)
      (if (= n 0)
      painter
      (let ((smaller (split-inner painter (- n 1))))
	(op2 painter (op1 smaller smaller)))))
    (lambda (painter n)
      (split-inner painter n)))
  (define up-split (split beside below))
  (define right-split (split below beside))
#+end_src

#+begin_src scheme :exports both :results raw value
<<pict-vect>>
<<make-frame>>
<<pict-segment>>
<<segments-painter>>
<<wave-segment>>
<<transform-painter>>
<<pict-frame>>
<<draw-line>>
<<beside>>
<<below-beside>>
<<rotate270>>
<<rotate90>>
<<split>>
((up-split wave 1) (make-frame (make-vect 0.0 1.0) (make-vect 1.0 0.0) (make-vect 0.0 -1.0)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./43404b14-9224-4b64-b304-7beebed2c3c8.png]]

#+begin_src scheme :exports both :results raw value
<<pict-vect>>
<<make-frame>>
<<pict-segment>>
<<segments-painter>>
<<wave-segment>>
<<transform-painter>>
<<pict-frame>>
<<draw-line>>
<<beside>>
<<below-beside>>
<<rotate270>>
<<rotate90>>
<<split>>
((right-split wave 1) (make-frame (make-vect 0.0 1.0) (make-vect 1.0 0.0) (make-vect 0.0 -1.0)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./b96c593e-a711-4824-a79c-4b4e911d1374.png]]

*** DONE Exercise 2.46 make-vect
    CLOSED: [2019-09-20 Fri 12:48]
#+begin_src scheme :exports both :results value :noweb-ref pict-vect
  (define (make-vect xcor ycor . o)
    (append (list xcor) (list ycor) o))
  (define (xcor-vect vect)
    (car vect))
  (define (ycor-vect vect)
    (cadr vect))
  (define (scale-vect scale vect)
    (map (lambda (x) (* x scale)) vect))
  (define (add-vect vec1 vec2)
    (map (lambda (cor1 cor2) (+ cor1 cor2)) vec1 vec2))
  (define (sub-vect vec1 vec2)
    (map (lambda (cor1 cor2) (- cor1 cor2)) vec1 vec2))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<pict-vect>>
(show #t (make-vect 1 2 3) "\n")
(show #t (xcor-vect (make-vect 1 2 3)) "\n")
(show #t (ycor-vect (make-vect 1 2 3)) "\n")
(show #t (scale-vect 2 (make-vect 1 2 3)) "\n")
(show #t (add-vect (make-vect 1 2 3) (make-vect 1 2 3)) "\n")
(show #t (sub-vect (make-vect 1 2 3) (make-vect 1 2 3)) "\n")
#+end_src

#+RESULTS:
: (1 2 3)
: 1
: 2
: (2 4 6)
: (2 4 6)
: (0 0 0)

*** DONE Exercise 2.47 make-frame
    CLOSED: [2019-09-20 Fri 14:48]
#+begin_src scheme :exports both :results value :noweb-ref make-frame
(define (make-frame origin edge1 edge2)
  (list origin edge1 edge2))
(define (origin-frame frame)
  (car frame))
(define (edge1-frame frame)
  (cadr frame))
(define (edge2-frame frame)
  (caddr frame))
#+end_src
#+begin_src scheme :exports both :results output
<<make-frame>>
<<pict-vect>>
(make-frame (make-vect 0.1 0.2) (make-vect 0.1 0.2) (make-vect 0.0 0.3))
(origin-frame (make-frame (make-vect 0.1 0.2) (make-vect 0.1 0.2) (make-vect 0.0 0.3)))
(edge1-frame  (make-frame (make-vect 0.1 0.2) (make-vect 0.1 0.2) (make-vect 0.0 0.3)))
(edge2-frame  (make-frame (make-vect 0.1 0.2) (make-vect 0.1 0.2) (make-vect 0.0 0.3)))
#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
<<pict-vect>>
  (define (make-frame origin edge1 edge2)
    (cons origin (cons edge1 edge2)))
  (define (origin-frame frame)
    (car frame))
  (define (edge1-frame frame)
    (cadr frame))
  (define (edge2-frame frame)
    (cddr frame))
  (show #t (origin-frame (make-frame (make-vect 0.1 0.2) (make-vect 0.1 0.2) (make-vect 0.0 0.3))) "\n")
  (show #t (edge1-frame (make-frame (make-vect 0.1 0.2) (make-vect 0.1 0.2) (make-vect 0.0 0.3))) "\n")
  (show #t (edge2-frame (make-frame (make-vect 0.1 0.2) (make-vect 0.1 0.2) (make-vect 0.0 0.3))) "\n")
#+end_src

#+RESULTS:
: (0.1 0.2)
: (0.1 0.2)
: (0.0 0.3)

*** DONE Exercise 2.48 make-segment
    CLOSED: [2019-09-20 Fri 16:06]
#+begin_src scheme :exports both :results value :noweb-ref pict-segment
  (define (make-segment start-vector end-vector)
    (list start-vector end-vector))
  (define (start-segment segment)
    (car segment))
  (define (end-segment segment)
    (cadr segment))
#+end_src

#+begin_src scheme :exports both :results raw value
  <<draw-line>>
  <<pict-segment>>
  <<segments-painter>>
  <<pict-vect>>
  <<make-frame>>
  <<pict-frame>>
  ((segments->painter
    (list
     (make-segment (make-vect 0 0) (make-vect 1 1))
     (make-segment (make-vect 0 1) (make-vect 1 0))))
   (make-frame (make-vect 0 0) (make-vect 0 1) (make-vect 1 0)))
  (canvas-refresh)
#+end_src

#+RESULTS:
[[/tmp/scheme-temp.gif]]

*** DONE Exercise 2.49 segments->painter applications
    CLOSED: [2019-09-20 Fri 23:10]

#+begin_src scheme :exports both :results value :noweb-ref x-painter
(define x-painter
  (segments->painter
    (list
     (make-segment (make-vect 0 0) (make-vect 1 1))
     (make-segment (make-vect 0 1) (make-vect 1 0)))))
#+end_src

#+begin_src scheme :exports both :results raw value
  <<draw-line>>
  <<pict-segment>>
  <<segments-painter>>
  <<pict-vect>>
  <<make-frame>>
  <<pict-frame>>
  <<x-painter>>
  (x-painter
   (make-frame (make-vect 0 0) (make-vect 0 1) (make-vect 1 0)))
  (canvas-refresh)
#+end_src

#+RESULTS:
[[./a58f8946-42b6-43c4-89a5-59e892599394.gif]]

This painter is not entirely accurate, because my background is black,
so the lines would coalesce with it. I therefore just moved the lines
a little bit inside.

#+begin_src scheme :exports both :results value :noweb-ref frame-boundary-painter
(define frame-boundary-painter
  (segments->painter
    (list
     (make-segment (make-vect 0.01 0.01) (make-vect 0.01 0.99))
     (make-segment (make-vect 0.01 0.99) (make-vect 0.99 0.99))
     (make-segment (make-vect 0.99 0.99) (make-vect 0.99 0.01))
     (make-segment (make-vect 0.99 0.01) (make-vect 0.01 0.01)))))
#+end_src

#+begin_src scheme :exports both :results raw value
  <<draw-line>>
  <<pict-segment>>
  <<segments-painter>>
  <<pict-vect>>
  <<make-frame>>
  <<pict-frame>>
  <<frame-boundary-painter>>

  (frame-boundary-painter
   (make-frame (make-vect 0.1 0.1) (make-vect 0.1 0.05) (make-vect 0.5 0)))
  (canvas-refresh)
#+end_src

#+RESULTS:
[[./c03f59fb-c473-4cc1-bb80-20c97e7e7594.gif]]

#+begin_src scheme :exports both :results value :noweb-ref diamond-painter
(define diamond-painter
  (segments->painter
    (list
     (make-segment (make-vect 0.01 0.5) (make-vect 0.5 0.99))
     (make-segment (make-vect 0.5 0.99) (make-vect 0.99 0.5))
     (make-segment (make-vect 0.99 0.5) (make-vect 0.5 0.01))
     (make-segment (make-vect 0.5 0.01) (make-vect 0.01 0.5)))))
#+end_src

#+begin_src scheme :exports both :results raw value
  <<draw-line>>
  <<pict-segment>>
  <<segments-painter>>
  <<pict-vect>>
  <<make-frame>>
  <<pict-frame>>
  <<diamond-painter>>

  (diamond-painter
   (make-frame (make-vect 0 0) (make-vect 0 1) (make-vect 1 0)))
  (canvas-refresh)
#+end_src

#+RESULTS:
[[./90918df1-a802-4df6-a10d-afc50547bc72.gif]]

Remark: the exercise 2.49d is ambiguous. The "Unofficial Texinfo Version"
differs with the official paper version in this respect, since in the paper
version the waving figurine is drawn with segments, whereas the UTF uses a
bitmap.
This is the rough solution to the "segment-based" version.

#+begin_src scheme :exports both :results value :noweb-ref wave-segment
(define wave 
   (segments->painter 
        (list 
               (make-segment (make-vect .25 0) (make-vect .35 .5)) 
               (make-segment (make-vect .35 .5) (make-vect .3 .6)) 
               (make-segment (make-vect .3 .6) (make-vect .15 .4)) 
               (make-segment (make-vect .15 .4) (make-vect 0 .65)) 
               (make-segment (make-vect 0 .65) (make-vect 0 .85)) 
               (make-segment (make-vect 0 .85) (make-vect .15 .6)) 
               (make-segment (make-vect .15 .6) (make-vect .3 .65)) 
               (make-segment (make-vect .3 .65) (make-vect .4 .65)) 
               (make-segment (make-vect .4 .65) (make-vect .35 .85)) 
               (make-segment (make-vect .35 .85) (make-vect .4 1)) 
               (make-segment (make-vect .4 1) (make-vect .6 1)) 
               (make-segment (make-vect .6 1) (make-vect .65 .85)) 
               (make-segment (make-vect .65 .85) (make-vect .6 .65)) 
               (make-segment (make-vect .6 .65) (make-vect .75 .65)) 
               (make-segment (make-vect .75 .65) (make-vect 1 .35)) 
               (make-segment (make-vect 1 .35) (make-vect 1 .15)) 
               (make-segment (make-vect 1 .15) (make-vect .6 .45)) 
               (make-segment (make-vect .6 .45) (make-vect .75 0)) 
               (make-segment (make-vect .75 0) (make-vect .6 0)) 
               (make-segment (make-vect .6 0) (make-vect .5 .3)) 
               (make-segment (make-vect .5 .3) (make-vect .4 0)) 
               (make-segment (make-vect .4 0) (make-vect .25 0)) 
        )
   )
)
#+end_src


#+begin_src scheme :exports both :results raw value
<<pict-vect>>
<<pict-frame>>
<<magick-vect>>
<<make-frame>>
<<pict-segment>>
<<segments-painter>>
<<wave-segment>>
<<draw-line>>
(wave (make-frame (make-vect 0.0 0.9) (make-vect 0.7 0) (make-vect 0 -0.7)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./d9f0731a-a257-49cf-a71d-f8d3ab9e33ed.png]]

*** DONE Exercise 2.50 flip-horiz and rotate270 and rotate180
    CLOSED: [2019-09-20 Fri 23:37]
0:27:00
#+begin_src scheme :exports both :results value :noweb-ref transform-painter
  (define (transform-painter painter origin corner1 corner2)
    (lambda (frame)
      (let ((m (frame-coord-map frame)))
	(let ((new-origin (m origin)))
	  (painter (make-frame
		    new-origin
		    (sub-vect (m corner1) new-origin)
		    (sub-vect (m corner2) new-origin)))))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref flip-horiz
  (define (flip-horiz painter)
    (transform-painter painter
		       (make-vect 1.0 0.0)
		       (make-vect 0.0 0.0)
		       (make-vect 1.0 1.0)))
#+end_src

#+begin_src scheme :exports both :results raw value
<<flip-horiz>>
<<pict-vect>>
<<pict-segment>>
<<segments-painter>>
<<transform-painter>>
<<make-frame>>
<<pict-frame>>
<<draw-line>>
<<wave-segment>>
(define bltr-line-painter
  (segments->painter
    (list
     (make-segment (make-vect 0.0 0.00) (make-vect 1 1.0)))))
((flip-horiz wave) (make-frame (make-vect 0 1) (make-vect 1 0) (make-vect 0 -1)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./869de2d3-55f5-429a-ad9d-4941405a8d73.png]]

#+begin_src scheme :exports both :results value :noweb-ref rotate180
  (define (rotate180 painter)
    (transform-painter painter
		       (make-vect 1.0 1.0)
		       (make-vect 0.0 1.0)
		       (make-vect 1.0 0.0)))
#+end_src

#+begin_src scheme :exports both :results raw value
<<rotate180>>
<<pict-vect>>
<<pict-segment>>
<<segments-painter>>
<<transform-painter>>
<<make-frame>>
<<pict-frame>>
<<draw-line>>
<<wave-segment>>
(define ne-arrow-painter
  (segments->painter
    (list
     (make-segment (make-vect 0.0 0.00) (make-vect 0.9 0.9))
     (make-segment (make-vect 0.9 0.9) (make-vect 0.9 0.7))
     (make-segment (make-vect 0.9 0.9) (make-vect 0.7 0.9)))))
#;(ne-arrow-painter (make-frame (make-vect 0 0) (make-vect 0 1) (make-vect 1 0)))
((rotate180 wave) (make-frame (make-vect 0 1) (make-vect 1 0) (make-vect 0 -1)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./51986072-473e-425b-959a-1bd81f471447.png]]

#+begin_src scheme :exports both :results value :noweb-ref rotate270
  (define (rotate270 painter)
    (transform-painter painter
		       (make-vect 0.0 1.0)
		       (make-vect 0.0 0.0)
		       (make-vect 1.0 1.0)))
#+end_src


#+begin_src scheme :exports both :results raw value
<<pict-vect>>
<<make-frame>>
<<rogers>>
<<transform-painter>>
<<pict-frame>>
<<draw-line>>
<<beside>>
<<below-beside>>
<<rotate270>>
<<pict-segment>>
<<segments-painter>>
<<wave-segment>>
#;((below rogers wave) (make-frame (make-vect 0.0 0.0) (make-vect 1.0 0.0) (make-vect 0.0 1.0)))
((rotate270 wave) (make-frame (make-vect 0.0 1.0) (make-vect 1.0 0.0) (make-vect 0.0 -1.0)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./33a0bb01-aa51-420c-964d-73d089388c6c.png]]

*** DONE Exercise 2.51 below
    CLOSED: [2019-09-22 Sun 18:50]

#+begin_src scheme :exports both :results value :noweb-ref beside
  (define (beside painter1 painter2)
    (let ((split-point (make-vect 0.5 0.0)))
      (let ((paint-left
	     (transform-painter
	      painter1
	      (make-vect 0.0 0.0)
	      split-point
	      (make-vect 0.0 1.0)))
	    (paint-right
	     (transform-painter
	      painter2
	      split-point
	      (make-vect 1.0 0.0)
	      (make-vect 0.5 1.0))))
	(lambda (frame)
	  (paint-left frame)
	  (paint-right frame)))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value :noweb-ref below
  (define (below painter1 painter2)
    (let ((split-point (make-vect 0.0 0.5)))
      (let ((paint-bottom
	     (transform-painter
	      painter1
	      (make-vect 0.0 0.5)
	      (make-vect 1.0 0.5)
	      (make-vect 0.0 1.0)))
	    (paint-top
	     (transform-painter
	      painter2
	      (make-vect 0.0 0.0)
	      (make-vect 1.0 0.0)
	      split-point)))
	(lambda (frame)
	  (paint-top frame)
	  (paint-bottom frame)))))

#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results raw value
<<pict-vect>>
<<make-frame>>
<<wave-segment>>
<<rogers>>
<<below>>
<<transform-painter>>
<<pict-frame>>
<<draw-line>>
((below wave wave) (make-frame (make-vect 0.0 0.0) (make-vect 1.0 0.0) (make-vect 0.0 1.0)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./24869881-98d4-4a72-87e8-8b3c095f408c.png]]

#+begin_src scheme :exports both :results value :noweb-ref below-beside
  (define (below painter1 painter2)
    (rotate90 (beside (rotate270 painter1) (rotate270 painter2))))
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value :noweb-ref rotate90
  (define (rotate90 painter)
    (transform-painter painter
		       (make-vect 1.0 0.0)
		       (make-vect 1.0 1.0)
		       (make-vect 0.0 0.0)))

#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results raw value
<<pict-vect>>
<<make-frame>>
<<pict-segment>>
<<segments-painter>>
<<wave-segment>>
<<transform-painter>>
<<pict-frame>>
<<draw-line>>
<<magick-vect>>
<<beside>>
<<below-beside>>
<<rotate270>>
<<rotate90>>
((below wave wave) (make-frame (make-vect 0.0 1.0) (make-vect 1.0 0.0) (make-vect 0.0 -1.0)))
#;((rotate270 rogers) (make-frame (make-vect 0.0 0.0) (make-vect 1.0 0.0) (make-vect 0.0 1.0)))
(canvas-refresh)
#+end_src

#+RESULTS:
[[./13aec801-0171-4497-841c-5fa9c603c73b.png]]


Remark: imagemagick is a horrible piece of software, even though we have
nothing better. 

*** DONE Exercise 2.52 modify square-limit
    CLOSED: [2019-09-24 Tue 12:25]

To complete this exercise, we would first need to implement the square limit.

#+begin_src scheme :exports both :results value :noweb-ref square-limit
    (define (square-limit painter n)
      (let ((combine4 (square-of-four flip-horiz identity
				      rotate180 flip-vert)))
	(combine4 (corner-split painter n))))

    (define (square-of-four tl tr bl br)
      (lambda (painter)
	(let ((top (beside (tl painter) (tr painter)))
	      (bottom (beside (bl painter) (br painter))))
	  (below bottom top))))

    (define (corner-split painter n)
      (if (= n 0)
	  painter
	  (let ((up (up-split painter (- n 1)))
		(right (right-split painter (- n 1))))
	    (let ((top-left (beside up up))
		  (bottom-right (below right right))
		  (corner (corner-split painter (- n 1))))
	      (beside (below painter top-left)
		      (below bottom-right corner))))))
  (define (flip-vert painter)
    (transform-painter painter
		       (make-vect 0.0 1.0)
		       (make-vect 1.0 1.0)
		       (make-vect 0.0 0.0)))
  (define (identity x)
    x)
#+end_src

Because the exercise requires modification of the existing functions (and I
don't want to advise them), I'd just splice all the source code into one block.

#+begin_src scheme :exports both :results raw value
    (define (square-limit painter n)
      (let ((combine4 (square-of-four flip-horiz identity
				      rotate180 flip-vert)))
	(combine4 (corner-split painter n))))

    (define (square-of-four tl tr bl br)
      (lambda (painter)
	(let ((top (beside (flip-horiz (tl painter)) (tr painter)))
	      (bottom (beside (bl painter) (br painter))))
	  (below bottom top))))

    (define (corner-split painter n)
      (if (= n 0)
	  painter
	  (let ((up (up-split painter (- n 1)))
		(right (right-split painter (- n 1))))
	    (let ((top-left (beside up up))
		  (bottom-right (below right right))
		  (corner (corner-split painter (- n 1))))
	      (below (below painter top-left)
		      (below bottom-right corner))))))
  (define (flip-vert painter)
    (transform-painter painter
		       (make-vect 0.0 1.0)
		       (make-vect 1.0 1.0)
		       (make-vect 0.0 0.0)))
  (define (identity x)
    x)
  (define (make-vect xcor ycor . o)
    (append (list xcor) (list ycor) o))
  (define (xcor-vect vect)
    (car vect))
  (define (ycor-vect vect)
    (cadr vect))
  (define (scale-vect scale vect)
    (map (lambda (x) (* x scale)) vect))
  (define (add-vect vec1 vec2)
    (map (lambda (cor1 cor2) (+ cor1 cor2)) vec1 vec2))
  (define (sub-vect vec1 vec2)
    (map (lambda (cor1 cor2) (- cor1 cor2)) vec1 vec2))
  (define (make-frame origin edge1 edge2)
    (list origin edge1 edge2))
  (define (origin-frame frame)
    (car frame))
  (define (edge1-frame frame)
    (cadr frame))
  (define (edge2-frame frame)
    (caddr frame))
  (define (make-segment start-vector end-vector)
    (list start-vector end-vector))
  (define (start-segment segment)
    (car segment))
  (define (end-segment segment)
    (cadr segment))
  (define (segments->painter segment-list)
    (lambda (frame)
      (for-each
       (lambda (segment)
	 (draw-line
	  ((frame-coord-map frame)
	   (start-segment segment))
	  ((frame-coord-map frame)
	   (end-segment segment))))
       segment-list)))
  (define wave 
     (segments->painter 
	  (list 
		 (make-segment (make-vect .25 0) (make-vect .35 .5)) 
		 (make-segment (make-vect .35 .5) (make-vect .3 .6)) 
		 (make-segment (make-vect .3 .6) (make-vect .15 .4)) 
		 (make-segment (make-vect .15 .4) (make-vect 0 .65)) 
		 (make-segment (make-vect 0 .65) (make-vect 0 .85)) 
		 (make-segment (make-vect 0 .85) (make-vect .15 .6)) 
		 (make-segment (make-vect .15 .6) (make-vect .3 .65)) 
		 (make-segment (make-vect .3 .65) (make-vect .4 .65)) 
		 (make-segment (make-vect .4 .65) (make-vect .35 .85)) 
		 (make-segment (make-vect .35 .85) (make-vect .4 1)) 
		 (make-segment (make-vect .4 1) (make-vect .6 1)) 
		 (make-segment (make-vect .6 1) (make-vect .65 .85)) 
		 (make-segment (make-vect .65 .85) (make-vect .6 .65)) 
		 (make-segment (make-vect .6 .65) (make-vect .75 .65)) 
		 (make-segment (make-vect .75 .65) (make-vect 1 .35)) 
		 (make-segment (make-vect 1 .35) (make-vect 1 .15)) 
		 (make-segment (make-vect 1 .15) (make-vect .6 .45)) 
		 (make-segment (make-vect .6 .45) (make-vect .75 0)) 
		 (make-segment (make-vect .75 0) (make-vect .6 0)) 
		 (make-segment (make-vect .6 0) (make-vect .5 .3)) 
		 (make-segment (make-vect .5 .3) (make-vect .4 0)) 
		 (make-segment (make-vect .4 0) (make-vect .25 0))
                 (make-segment (make-vect 0.45 0.5) (make-vect 0.50 0.45))
                 (make-segment (make-vect 0.5 0.45) (make-vect 0.55 0.50)) 
	  )
     )
  )
  (define (transform-painter painter origin corner1 corner2)
    (lambda (frame)
      (let ((m (frame-coord-map frame)))
	(let ((new-origin (m origin)))
	  (painter (make-frame
		    new-origin
		    (sub-vect (m corner1) new-origin)
		    (sub-vect (m corner2) new-origin)))))))
  (define (frame-coord-map frame)
    (lambda (v)
     (add-vect
       (origin-frame frame)
	      (add-vect (scale-vect (xcor-vect v) (edge1-frame frame))
		 (scale-vect (ycor-vect v) (edge2-frame frame))))))
  (define canvas-size
    (make-parameter
     200
     (lambda (size)
       (if (and (exact-integer? size) (<= 2 size 1000))
	   size
	   (error "invalid canvas size")))))
  (define canvas-file-name
     (make-parameter
	(string-append "./" (substring (process->string "uuidgen") 0 36) ".png")
	(lambda (name)
	  (if (string? name)
	      name
	      (error "invalid canvas file name")))))
  (define (canvas-reset)
    (system "rm" (canvas-file-name))
    (system "convert" "xc:white"
	    "-scale" (string-append
		      (number->string (canvas-size))
		      "x"
		      (number->string (canvas-size)))
	    (canvas-file-name)))
  (define (canvas-refresh)
    (string-append "[[" (canvas-file-name) "]]"))
  (canvas-reset)
  (define (draw-line point1 point2)
    (system "mogrify"
	    "-fill" "black"
	    "-draw" (string-append "line "
				   (number->string (* (canvas-size) (car point1)))
				   ","
				   (number->string (* (canvas-size) (cadr point1)))
				   " "
				   (number->string (* (canvas-size) (car point2)))
				   ","
				   (number->string (* (canvas-size) (cadr point2))))
	    (canvas-file-name))
    (string-append "[[" (canvas-file-name) "]]"))
  (define (beside painter1 painter2)
    (let ((split-point (make-vect 0.5 0.0)))
      (let ((paint-left
	     (transform-painter
	      painter1
	      (make-vect 0.0 0.0)
	      split-point
	      (make-vect 0.0 1.0)))
	    (paint-right
	     (transform-painter
	      painter2
	      split-point
	      (make-vect 1.0 0.0)
	      (make-vect 0.5 1.0))))
	(lambda (frame)
	  (paint-left frame)
	  (paint-right frame)))))
  (define (below painter1 painter2)
    (rotate90 (beside (rotate270 painter1) (rotate270 painter2))))
  (define (rotate270 painter)
    (transform-painter painter
		       (make-vect 0.0 1.0)
		       (make-vect 0.0 0.0)
		       (make-vect 1.0 1.0)))
  (define (rotate90 painter)
    (transform-painter painter
		       (make-vect 1.0 0.0)
		       (make-vect 1.0 1.0)
		       (make-vect 0.0 0.0)))

  (define (rotate180 painter)
    (transform-painter painter
		       (make-vect 1.0 1.0)
		       (make-vect 0.0 1.0)
		       (make-vect 1.0 0.0)))
  (define (split op1 op2)
    (define (split-inner painter n)
      (if (= n 0)
      painter
      (let ((smaller (split-inner painter (- n 1))))
	(op2 painter (op1 smaller smaller)))))
    (lambda (painter n)
      (split-inner painter n)))
  (define up-split (split beside below))
  (define right-split (split below beside))
  (define (flip-horiz painter)
    (transform-painter painter
		       (make-vect 1.0 0.0)
		       (make-vect 0.0 0.0)
		       (make-vect 1.0 1.0)))
  ((square-limit wave 1) (make-frame (make-vect 0.0 1.0) (make-vect 1.0 0.0) (make-vect 0.0 -1.0)))
  (canvas-refresh)
#+end_src

#+RESULTS:
[[./f2d16f96-de16-45f7-9f7f-1e31397e4d61.png]]

 a. I added a check-mark at the segments->painter level.
 b. Replaced the last ~beside~ with ~below~ at the lowest level.
 c. Added a ~flip-horiz~ at the level of the ~square-of-four~.

*** Remark. Here the picture language chapter stops
The bitmap loader used by the ~rogers~ painter is not very reliable, so it
will not probably be able to replicate the full ~square-limit~. You can try
though. 
*** DONE Exercise 2.53 quote introduction
    CLOSED: [2019-09-24 Tue 12:36]
#+begin_src scheme :exports both :results output
(show #t (list 'a 'b 'c) "\n")
(show #t (list (list 'george)) "\n")
(show #t (cdr '((x1 x2) (y1 y2))) "\n")
(show #t (cadr '((x1 x2) (y1 y2))) "\n")
(show #t (pair? (car '(a short list))) "\n")
(show #t (memq 'red '((red shoes) (blue socks))) "\n")
(show #t (memq 'red '(red shoes blue socks)) "\n")
#+end_src

#+RESULTS:
: (a b c)
: ((george))
: ((y1 y2))
: (y1 y2)
: #f
: #f
: (red shoes blue socks)

*** DONE Exercise 2.54 equal? implementation
    CLOSED: [2019-09-24 Tue 13:48]
#+begin_src scheme :exports both :results output :noweb-ref equal-implementation
  (define (equal? o1 o2)
    (cond ((eq? o1 o2) #t)
	  ((and (list? o1) (list? o2))     (accumulate (lambda (x y) (and x y)) #t (map equal? o1 o2)))
	  ((and (number? o1) (number? o2)) (= o1 o2))
	  (else #f)))
#+end_src

#+RESULTS:


#+begin_src scheme :exports both :results output
<<accumulate>>

<<equal-implementation>>

(show #t (equal? '(this is a list) '(this is a list)) "\n")
(show #t (equal? '(this is a list) '(this (is a) list)) "\n")
#+end_src

#+RESULTS:
: #t
: #f

*** DONE Exercise 2.55 quote quote
    CLOSED: [2019-09-24 Tue 13:48]
This is really easy.
~(car ''abracadabra)~ is in reality ~(car (quote (quote abracadabra)))~. The
second ~'~ gets automatically translated into a ~quote~ and is not interpreted.
*** DONE Exercise 2.56 differentiation-exponentiation
    CLOSED: [2019-09-24 Tue 23:14]
#+begin_src scheme :exports both :results value :noweb-ref deriv-basic
  (define (deriv exp var)
    (cond ((number? exp) 0)
	  ((variable? exp) (if (same-variable? exp var) 1 0))
	  ((sum? exp) (make-sum (deriv (addend exp) var)
				(deriv (augend exp) var)))
	  ((product? exp)
	   (make-sum
	    (make-product (multiplier exp)
			  (deriv (multiplicand exp) var))
	    (make-product (deriv (multiplier exp) var)
			  (multiplicand exp))))
	  (else
	   (error "unknown expression type: DERIV" exp))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref deriv-components
  (define (variable? x) (symbol? x))
  (define (same-variable? v1 v2)
    (and (variable? v1) (variable? v2) (eq? v1 v2)))
  (define (=number? exp num)
    (and (number? exp) (= exp num)))
#+end_src
  
#+begin_src scheme :exports both :results value :noweb-ref deriv-operations
  (define (make-sum a1 a2 . rest)
    (cond ((=number? a1 0) a2)
	  ((=number? a2 0) a1)
	  ((and (number? a1) (number? a2))
	   (+ a1 a2))
	  (else (list '+ a1 a2))))
  (define (make-product m1 m2)
    (cond ((or (=number? m1 0) (=number? m2 0)) 0)
	  ((=number? m1 1) m2)
	  ((=number? m2 1) m1)
	  ((and (number? m1) (number? m2)) (* m1 m2))
	  (else (list '* m1 m2))))
  (define (sum? x) (and (pair? x) (eq? (car x) '+)))
  (define (addend s) (cadr s))
  (define (augend s) (caddr s))
  (define (product? x) (and (pair? x) (eq? (car x) '*)))
  (define (multiplier p) (cadr p))
  (define (multiplicand p) (caddr p))

#+end_src

#+begin_src scheme :exports both :results output
<<deriv-basic>>
<<deriv-components>>
<<deriv-operations>>
(show #t (deriv '(+ x 3) 'x) "\n")
(show #t (deriv '(* x y) 'x) "\n")
(show #t (deriv '(* (* x y) (+ x 3)) 'x) "\n")
#+end_src

#+RESULTS:
: 1
: y
: (+ (* x y) (* y (+ x 3)))

#+begin_src scheme :exports both :results value :noweb-ref deriv-and-exponent

  (define (deriv exp var)
    (cond ((number? exp) 0)
	  ((variable? exp) (if (same-variable? exp var) 1 0))
	  ((sum? exp) (make-sum (deriv (addend exp) var)
				(deriv (augend exp) var)))
	  ((product? exp)
	   (make-sum
	    (make-product 
	     (multiplier exp)
	     (deriv
	      (multiplicand exp)
	      var))
	    (make-product
	     (deriv
	      (multiplier exp)
	      var)
	     (multiplicand exp))))
	  ((exponentiation? exp)
	   (make-product (exponent exp)
			 (make-product
			  (make-exponentiation
			   (base exp)
			   (make-sum (exponent exp) -1))
			  (deriv (base exp) var))))
	  (else
	   (error "unknown expression type: DERIV" exp))))

  (define (make-exponentiation base power)
    (cond ((=number? power 0) 1)
	  ((=number? power 1) base)
	  ((and (number? base) (number? power))
	   (expt base power))
	  (else (list '** base power))))
  (define (exponentiation? x) (and (pair? x) (eq? (car x) '**)))
  (define (base s) (cadr s))
  (define (exponent s) (caddr s))

#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<deriv-and-exponent>>
<<deriv-components>>
<<deriv-operations>>
(show #t (deriv '(** x 3) 'x) "\n")
(show #t (deriv '(** (* (* x y) (+ x 3)) 5) 'x) "\n")
#+end_src

#+RESULTS:
: (* 3 (** x 2))
: (* 5 (* (** (* (* x y) (+ x 3)) 4) (+ (* x y) (* y (+ x 3)))))

*** DONE Exercise 2.57 differentiate-three-sum
    CLOSED: [2019-09-25 Wed 12:40]
#+begin_src scheme :exports both :results value :noweb-ref deriv-operations-three
  (define (make-sum a1 a2 . rest)
    (if (null? rest)
	(cond ((=number? a1 0) a2)
	      ((=number? a2 0) a1)
	      ((and (number? a1) (number? a2))
	       (+ a1 a2))
	      (else (list '+ a1 a2)))
	(make-sum a1 (apply make-sum a2 (car rest) (cdr rest)))))
  (define (make-product m1 m2 . rest)
    (if (null? rest)
	(cond ((or (=number? m1 0) (=number? m2 0)) 0)
	  ((=number? m1 1) m2)
	  ((=number? m2 1) m1)
	  ((and (number? m1) (number? m2)) (* m1 m2))
	  (else (list '* m1 m2)))
	(make-product m1 (apply make-product m2 (car rest) (cdr rest)))))
  (define (sum? x) (and (pair? x) (eq? (car x) '+)))
  (define (addend s) (cadr s))
  (define (augend s)
    (if (null? (cdddr s))
	(caddr s)
	(apply make-sum (cddr s))))
  (define (product? x) (and (pair? x) (eq? (car x) '*)))
  (define (multiplier p) (cadr p))
  (define (multiplicand p)
    (if (null? (cdddr p))
	(caddr p)
	(apply make-product (cddr p))))

#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<deriv-and-exponent>>
<<deriv-components>>
<<deriv-operations-three>>
(show #t (deriv '(** x 3) 'x) "\n")
(show #t (deriv '(* x y z) 'y) "\n")
(show #t (deriv '(** (* (* x y z) (+ x 3)) 5) 'x) "\n")
#+end_src

#+RESULTS:
: (* 3 (** x 2))
: (* x z)
: (* 5 (* (** (* (* x y z) (+ x 3)) 4) (+ (* x y z) (* (* y z) (+ x 3)))))

*** DONE Exercise 2.58 infix-notation
    CLOSED: [2019-09-25 Wed 15:21]

This solution is copied from http://community.schemewiki.org/?sicp-ex2.58
almost verbatim. Courtesy of sgm.

#+begin_src scheme :exports both :results output
(define (singleton? lst)
  (= 1 (length lst)))
(define (sum? expr) 
   (eq? '+ (smallest-op expr))) 
  
 (define (product? expr) 
   (eq? '* (smallest-op expr))) 
(define (smallest-op expr) 
   (accumulate (lambda (a b) 
                 (if (operator? b) 
                     (min-precedence a b) 
                     a)) 
               'maxop 
               expr))
(define *precedence-table* 
   '( (maxop . 10000) 
      (minop . -10000) 
      (+ . 0) 
      (* . 1) )) 
  
 (define (operator? x) 
   (define (loop op-pair) 
     (cond ((null? op-pair) #f) 
           ((eq? x (caar op-pair)) #t) 
           (else (loop (cdr op-pair)))))
   (loop *precedence-table*)) 
 (define (min-precedence a b) 
   (if (precedence<? a b) 
       a 
       b))   
 (define (precedence<? a b) 
   (< (precedence a) (precedence b))) 
 (define (precedence op) 
   (define (loop op-pair) 
     (cond ((null? op-pair) 
            (error "Operator not defined -- PRECEDENCE:" op)) 
           ((eq? op (caar op-pair)) 
            (cdar op-pair)) 
           (else 
            (loop (cdr op-pair))))) 
   (loop *precedence-table*)) 
(define (augend expr) 
   (let ((a (cdr (memq '+ expr)))) 
     (if (singleton? a) 
         (car a) 
         a)))

(define (prefix sym list) 
   (if (or (null? list) (eq? sym (car list))) 
       '() 
       (cons (car list) (prefix sym (cdr list))))) 
  
 (define (addend expr) 
   (let ((a (prefix '+ expr))) 
     (if (singleton? a) 
         (car a) 
         a))) 
(define (make-sum a1 a2) 
   (cond ((=number? a1 0) a2) 
         ((=number? a2 0) a1) 
         ((and (number? a1) (number? a2)) 
          (+ a1 a2)) 
         (else (list a1 '+ a2)))) 
(define (multiplier expr) 
   (let ((m (prefix '* expr))) 
     (if (singleton? m) 
         (car m) 
         m))) 
  
 (define (multiplicand expr) 
   (let ((m (cdr (memq '* expr)))) 
     (if (singleton? m) 
         (car m) 
         m))) 
  
 (define (make-product m1 m2) 
   (cond ((=number? m1 1)  m2) 
         ((=number? m2 1)  m1) 
         ((or (=number? m1 0) (=number? m2 0))  0) 
         ((and (number? m1) (number? m2)) 
          (* m1 m2)) 
         (else (list m1 '* m2))))
<<deriv-components>>
<<deriv-and-exponent>>
<<accumulate>>

(show #t (smallest-op '(t + k)) "\n")
(show #t (deriv '(x + 3) 'x) "\n") 
(show #t (deriv '(x * y * (x + 3)) 'x) "\n")
(show #t (deriv '((x * y) * (x + 3)) 'x) "\n")
(show #t (deriv '(x * (y * (x + 3))) 'x) "\n")

#+end_src

#+RESULTS:
: +
: 1
: ((x * y) + (y * (x + 3)))
: ((x * y) + (y * (x + 3)))
: ((x * y) + (y * (x + 3)))


As a side-note: sometimes people say that copying other people's code
prevents us from learning. I disagree. Only copying sgm's code allowed me to
find a serious bug in my implementation of "accumulate". 

*** DONE Exercise 2.59 union-set
    CLOSED: [2019-09-25 Wed 22:00]

#+begin_src scheme :exports both :results value :noweb-ref element-of-set

  (define (element-of-set? x set)
    (cond ((null? set) false)
	  ((equal? x (car set)) true)
	  (else (element-of-set? x (cdr set)))))
#+end_src

#+begin_src scheme :exports both :results value :noweb-ref union-set
<<element-of-set>>
  (define (union-set set1 set2)
    (append set1 (filter (lambda (x) (not (element-of-set? x set1))) set2)))

  (define true #t)
  (define false #f)
#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
<<union-set>>
<<filter>>
(show #t " " (union-set '(1 2 3 4) '(3 4 5 6)))
#+end_src

#+RESULTS:
:  (1 2 3 4 5 6)

*** DONE Exercise 2.60 duplicate-set
    CLOSED: [2019-09-25 Wed 22:17]

#+begin_src scheme :exports both :results output
  (define (element-of-set? x set)
    (cond ((null? set) false)
	  ((equal? x (car set)) true)
	  (else (element-of-set? x (cdr set)))))
  #;(The element-of-set? predicate stays the same)
  (define (adjoin x set)
    (cons x set))

  (define (intersection-set set1 set2)
    (cond ((or (null? set1) (null? set2)) '())
	  ((element-of-set? (car set1) set2)
	   (cons (car set1) (intersection-set (cdr set1) set2)))
	  (else (intersection-set (cdr set1) set2))))
  #;(The intersection-set stays the same, moreover, every time it is called, 
  the duplicates are removed.)

  (define (union-set set1 set2)
    (append set1 set2))
  (define true #t)
  (define false #f)  

  (show #t " " (element-of-set? 2 '(1 2 3)) "\n")
  (show #t " " (adjoin 2 '(1 2)) "\n")
  (show #t " " (intersection-set '(1 2 3 4 5) '(2 2 2 2 2)) "\n")
  (show #t " " (union-set '(1 2 3 4 5) '(1 2 2 2 2 3 4)) "\n")
#+end_src

#+RESULTS:
:  #t
:  (2 1 2)
:  (2)
:  (1 2 3 4 5 1 2 2 2 2 3 4)

The efficiency of ~element-of-set?~ is still O(n), although on average sets
would be larger. ~adjoin~ takes O(1), instead of O(n). ~intersection-set~
takes the same \(O(n^2)\), although again, the sets may be larger. ~union-set~
takes \(O(1)\) instead of \(O(n^2)\), which sounds even too good to be true.

Well, if the amount of calls to ~intersection-set~ is big enough, I think
that this representation would be good enough, or even faster.

*** DONE Exercise 2.61 sets as ordered lists
    CLOSED: [2019-09-26 Thu 21:44]

#+begin_src scheme :exports both :results value
  (define (adjoin-set x set)
    (cond ((null? set) x)
	  ((= x (car set)) set)
	  ((< x (car set)) (cons x set))
	  (else (cons (car set) (adjoin-set x (cdr set))))))
  (adjoin-set 3 '(1 2 4 5))
#+end_src

#+RESULTS:
| 1 | 2 | 3 | 4 | 5 |

*** DONE Exercise 2.62 ordered-union-set (ordered list)
    CLOSED: [2019-09-26 Thu 21:38]

#+begin_src scheme :exports both :results raw value :noweb-ref ordered-set
  (define (element-of-set? x set)
    (cond ((null? set) false)
	  ((= x (car set)) true)
	  ((< x (car set)) false)
	  (else (element-of-set? x (cdr set)))))
  (define (intersection-set set1 set2)
    (if (or (null? set1) (null? set2))
	'()
	(let ((x1 (car set1)) (x2 (car set2)))
	  (cond ((= x1 x2)
		 (cons x1
		       (intersection-set (cdr set1)
					 (cdr set2))))
		((< x1 x2)
		 (intersection-set (cdr set1) set2))
		((< x2 x1)
		 (intersection-set set1 (cdr set2)))))))

  (define (remove-duplicates-set set)
    (define (r-d-iter set accumulator)
      (cond ((null? set) accumulator)
	    ((null? accumulator) (r-d-iter (cdr set) (cons (car set) accumulator)))
	    ((= (car set) (car accumulator)) (r-d-iter (cdr set) accumulator))
	    (else (r-d-iter (cdr set) (cons (car set) accumulator)))))
    (reverse (r-d-iter set '())))


  (define (union-set set1 set2)
    (define (union-iter set1 set2 result)
      (cond ((null? set1) (append (reverse result) set2))
	    ((null? set2) (append (reverse result) set1))
	    ((<= (car set1) (car set2)) (union-iter (cdr set1) set2 (cons (car set1) result)))
	    ((<= (car set2) (car set1)) (union-iter set1 (cdr set2) (cons (car set2) result)))))
    (remove-duplicates-set (union-iter set1 set2 '())))
#+end_src

#+begin_src scheme :exports both :results raw value 
<<ordered-set>>
(cons (union-set '(1 3 10) '(1 2 4 5))
(intersection-set '(1 3 10) '(1 2 4 5)))
#+end_src

#+RESULTS:
| (1 2 3 4 5 10) | 1 |

*** TODO Figure 2.16 Various binary trees that represent the set {1,3,5,7,9,11}.
*** DONE Exercise 2.63 tree->list (binary search tree)
    CLOSED: [2019-09-26 Thu 23:37]

Let me copy the two code pieces here, I will need them later.

#+begin_src scheme :exports both :results raw value
  (define (tree->list-1 tree)
    (if (null? tree)
	'()
	(append (tree->list-1 (left-branch tree))
		(cons (entry tree)
		      (tree->list-1 (right-branch tree))))))
#+end_src

#+begin_src scheme :exports both :results raw value :noweb-ref tree-list
  (define (tree->list-2 tree)
    (define (copy-to-list tree result-list)
      (if (null? tree)
	  result-list
	  (copy-to-list (left-branch tree)
			(cons (entry tree)
			      (copy-to-list (right-branch tree)
					    result-list)))))
    (copy-to-list tree '()))

#+end_src


 a. The difference between the two functions is the order of traversing the
 tree. The function ~tree->list-1~ traverses the tree from the left, whereas
 the function ~tree->list-2~ does it from the right. The outcome would be the
 same, and for the trees on the figure 2.16 would give the same answer: 
 ~'(1 2 3 4 5 6 7 8 9 10 11)~.
 b. The difference in performance would be significant. The function 2 uses
 ~cons~, which uses O(1) operations, so the opppprder of growth is ~O(n)~ in
 total. ~append~ in the function 1 takes O(n) operations in the worst case,
 which would make the total complexity \(O(n^2)\).p
*** DONE Exercise 2.64 balanced-tree
    CLOSED: [2019-09-29 Sun 17:22]

Firstly, I want to see what it is exactly that the function outputs.

#+begin_src scheme :exports both :results output :noweb-ref list-tree
     (define (entry tree) (car tree))

     (define (left-branch tree) (cadr tree))

     (define (right-branch tree) (caddr tree))

     (define (make-tree entry left right)
       (list entry left right))


  (define (list->tree elements)
    (car (partial-tree elements (length elements))))

  (define (partial-tree elts n)
    (if (= n 0)
	(cons '() elts)
	(let ((left-size (quotient (- n 1) 2)))
	  (let ((left-result (partial-tree elts left-size)))
	    (let ((left-tree (car left-result))
		  (non-left-elts (cdr left-result))
		  (right-size (- n (+ left-size 1))))
	      (let ((this-entry (car non-left-elts))
		    (right-result (partial-tree (cdr non-left-elts)
						right-size)))
		(let ((right-tree (car right-result))
		      (remaining-elts (cdr right-result)))
		  (cons (make-tree this-entry left-tree right-tree)
			remaining-elts))))))))
#+end_src

#+begin_src scheme :exports both :results output
<<list-tree>>
(show #t " " (pretty (list->tree '(1 3 5 7 9 11))))
#+end_src

#+RESULTS:
:  (5 (1 () (3 () ())) (9 (7 () ()) (11 () ())))

Since I already got the result, I will just draw it.

 #+begin_src plantuml :exports both :file figure-1-1-dot.png
 @startdot
 graph g {
	 node [shape=plaintext];
	 A1 [label="5"];

	 B1 [label="1"];

	 B3 [label="9"];

	 C1 [label="7"];
	 C2 [label="11"];
         C0 [label="'()"];
         C3 [label="3"]

 // edges
	 A1 -- B1;
	 A1 -- B3;
         
         B1 -- C0;
         B1 -- C3;
	 
          
	 B3 -- C1;
	 B3 -- C2;
	 
	 { rank=same; A1 }
	 { rank=same; B1 B3 } 
	 { rank=same; C1 C2 C3 }
 } 
 @enddot
 #+end_src 

 #+RESULTS:
 [[file:figure-1-1-dot.png]]

   a. How exactly did this tree appear? The algorithm given by Abelson
and Sussman is actually quite straightforward: divide a list into two
roughly equal parts, separated by the middle element, make the element into a
node, and attach the right and the left sub-lists of the list as its left and
right children.

   b. The function ~partial-tree~ doesn't contain any full passes through the list,
works in constant time, and is evaluated once per node. Therefore the
complexity is O(1).

*** DONE Exercise 2.65 tree-union-set
    CLOSED: [2019-10-09 Wed 12:13]
Well, I am required to make a union-set and an intersection-set.
So far, we have the operations tree->list, which works in O(n); list->tree,
which works as O(n) too, and union-set and intersection-set for list-based
set implementations, which both work in O(n). The solution then seems
straightforward. 



#+begin_src scheme :exports both :results raw value :noweb-ref set-tree
  (define (union-set-tree set1 set2)
    (list->tree (union-set (tree->list-2 set1) (tree->list-2 set2))))

  (define (intersection-set-tree set1 set2)
    (list->tree (intersection-set (tree->list-2 set1) (tree->list-2 set2))))
#+end_src

#+begin_src scheme :exports both :results output
<<list-tree>>
<<tree-list>>
<<ordered-set>>
<<set-tree>>

(show #t (union-set-tree (list->tree '(1 3 10)) (list->tree '(1 2 4 5))) "\n")
(show #t (intersection-set-tree (list->tree '(1 3 10)) (list->tree '(1 2 4 5))) "\n")
   
#+end_src

#+RESULTS:
: (3 (1 () (2 () ())) (5 (4 () ()) (10 () ())))
: (1 () ())

*** DONE Exercise 2.66 tree-lookup
    CLOSED: [2019-10-09 Wed 13:03]

The excellent property of the ~list->tree~ procedure is that is asserts that
the list given as an argument is already sorted in some way appropriate for
this represented data. Therefore we can use the function verbatim.

#+begin_src scheme :exports both :results raw value :noweb-ref tree-lookup
  (define-record-type dict-entry-type
  (dict-entry x y)
  dict-entry?
  (x entry-key)
  (y entry-value))

  (define (tree-lookup key dictionary)
    (cond ((null? dictionary) #f)
	  ((= (entry-key (entry dictionary)) key) (entry dictionary))
	  ((<= key (entry-key (entry dictionary))) (tree-lookup key (left-branch dictionary)))
	  ((>= key (entry-key (entry dictionary))) (tree-lookup key (right-branch dictionary)))
	  (else (error "Corrupt dictionary"))))

#+end_src

#+begin_src scheme :exports both :results output
<<list-tree>>
<<tree-lookup>>
(show #t " " (list->tree (list (dict-entry 1 'John) (dict-entry 2 'James) (dict-entry 3 'Baloo) (dict-entry 4 'Carry))) "\n")
(show #t " " (tree-lookup 3 (list->tree (list (dict-entry 1 'John) (dict-entry 2 'James) (dict-entry 3 'Baloo) (dict-entry 4 'Carry)))) "\n")
#+end_src

#+RESULTS:
:  ({dict-entry-type #63 2 James} ({dict-entry-type #63 1 John} () ()) ({dict-entry-type #63 3 Baloo} () ({dict-entry-type #63 4 Carry} () ())))
:  {dict-entry-type #63 3 Baloo}

This exercise used the r7rs ~define-record-type~. It is not strictly
necessary here, but I used it do add more "encapsulation" to the data base.
*** DONE Exercise 2.67 Huffman decode a simple message
    CLOSED: [2019-10-09 Wed 20:20]

#+begin_src scheme :exports both :results value :noweb-ref huffman-base
     (define (make-leaf symbol weight)
       (list 'leaf symbol weight))

     (define (leaf? object)
       (eq? (car object) 'leaf))

     (define (symbol-leaf x) (cadr x))

     (define (weight-leaf x) (caddr x))

     (define (make-code-tree left right)
       (list left
             right
             (append (symbols left) (symbols right))
             (+ (weight left) (weight right))))
     (define (left-branch tree) (car tree))

     (define (right-branch tree) (cadr tree))

     (define (symbols tree)
       (if (leaf? tree)
           (list (symbol-leaf tree))
           (caddr tree)))

     (define (weight tree)
       (if (leaf? tree)
           (weight-leaf tree)
           (cadddr tree)))
     (define (decode bits tree)
       (define (decode-1 bits current-branch)
         (if (null? bits)
             '()
             (let ((next-branch
                    (choose-branch (car bits) current-branch)))
               (if (leaf? next-branch)
                   (cons (symbol-leaf next-branch)
                         (decode-1 (cdr bits) tree))
                   (decode-1 (cdr bits) next-branch)))))
       (decode-1 bits tree))

     (define (choose-branch bit branch)
       (cond ((= bit 0) (left-branch branch))
             ((= bit 1) (right-branch branch))
             (else (error "bad bit -- CHOOSE-BRANCH" bit))))
     (define (adjoin-set x set)
       (cond ((null? set) (list x))
             ((< (weight x) (weight (car set))) (cons x set))
             (else (cons (car set)
                         (adjoin-set x (cdr set))))))
     (define (make-leaf-set pairs)
       (if (null? pairs)
           '()
           (let ((pair (car pairs)))
             (adjoin-set (make-leaf (car pair)    #;(symbol)
                                    (cadr pair))  #;(frequency)
                         (make-leaf-set (cdr pairs))))))

#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results value :noweb-ref huffman-sample-tree
  (define sample-tree
    (make-code-tree (make-leaf 'A 4)
		    (make-code-tree
		     (make-leaf 'B 2)
		     (make-code-tree (make-leaf 'D 1)
				     (make-leaf 'C 1)))))
  (define sample-message '(0 1 1 0 0 1 0 1 0 1 1 1 0))

#+end_src

#+begin_src scheme :exports both :results value

<<huffman-base>>
<<huffman-sample-tree>>
  (decode sample-message sample-tree)
#+end_src

#+RESULTS:
| A | D | A | B | B | C | A |

This is a rather easy exercise, who's main goal is to make us test that the
chapter code is actually working.

*** DONE Exercise 2.68 Huffman encode a simple message
    CLOSED: [2019-10-09 Wed 20:53]

#+begin_src scheme :exports both :results raw value :noweb-ref huffman-encode
	(define (encode message tree)
	  (if (null? message)
	      '()
	      (append (encode-symbol (car message) tree)
		      (encode (cdr message) tree))))
	(define (encode-symbol symbol tree)
	  (cond ((not (element-of-set? symbol (symbols tree)))
		 (error "Error: Huffman tree does not support encoding symbol" symbol))
		((leaf? tree) '())
		((element-of-set? symbol (symbols (left-branch tree))) (cons 0 (encode-symbol symbol (left-branch tree))))
		((element-of-set? symbol (symbols (right-branch tree))) (cons 1 (encode-symbol symbol (right-branch tree))))))
	      
#+end_src

#+begin_src scheme :exports both :results value
(define true #t)
(define false #f)
<<huffman-base>>
<<huffman-encode>>
<<element-of-set>>
<<huffman-sample-tree>>
(encode (list 'A  'D  'A  'B  'B  'C  'A) sample-tree)
#+end_src

#+RESULTS:
| 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 |

My implementation of encode-symbol is not iterative, but for educational
purposes it should be enough.

*** DONE Exercise 2.69 Generate Huffman tree
    CLOSED: [2019-10-10 Thu 11:28]

I spent an hour trying to debug why my code doesn't work, and it turns out
that although Abelson and Sussman use the word "pair" for the (symbol,
weight) tuples, they are actually lists.

#+begin_src scheme :exports both :results value :noweb-ref huffman-generate-tree
     (define (generate-huffman-tree pairs)
       (successive-merge (make-leaf-set pairs)))
     #;(leaf-set is sorted by weight)
     (define (successive-merge leaf-set)
       (cond ((null? leaf-set) '())
	     ((null? (cdr leaf-set)) (car leaf-set))
	     (else (successive-merge (adjoin-set
				      (make-code-tree
				       (car leaf-set)
				       (cadr leaf-set))
				      (cddr leaf-set))))))
#+end_src

#+begin_src scheme :exports both :results output
(define true #t)
(define false #f)
<<huffman-base>>
<<huffman-encode>>
<<element-of-set>>
<<huffman-sample-tree>>
<<huffman-generate-tree>>
(define pairs (list (list 'A 4) (list 'B 2) (list 'C 1) (list 'D 1)))
n#;(generate-huffman-tree (list (cons 'A 4) (cons 'B 2) (cons 'C 1) (cons 'D 1)))
#n;(make-leaf-set pairs)
(show #t  "Sample-tree:" (pretty (generate-huffman-tree pairs)) "\n")
(show #t  "Our tree   :" (pretty sample-tree) "\n")
#+end_src

#+RESULTS:
#+begin_example
Sample-tree:((leaf A 4)
             ((leaf B 2) ((leaf D 1) (leaf C 1) (D C) 2) (B D C) 4)
             (A B D C)
             8)

Our tree   :((leaf A 4)
             ((leaf B 2) ((leaf D 1) (leaf C 1) (D C) 2) (B D C) 4)
             (A B D C)
             8)

#+end_example

*** DONE Exercise 2.70 Generate a tree and encode a song
    CLOSED: [2019-10-10 Thu 13:11]
This exercise has a small caveat. The scheme used to create examples for SICP
back when it was written, had a case-independent reader, therefore the text
of the book ignores the case difference between, say, 'Sha, 'SHA, and 'sha.
Luckily, in the given song, there are no instances of the same symbol
consisting of letters of different cases, so to make the code work, the only
thing needed is to correct the case in the dictionary.

Let's generate a tree first:

#+begin_src scheme :exports both :results output
  (define true #t)
  (define false #f)
  <<huffman-base>>
  <<huffman-encode>>
  <<element-of-set>>
  <<huffman-sample-tree>>
  <<huffman-generate-tree>>
  (define pairs 
    (list
     (list 'a 4) (list 'Get 2) (list 'Sha 1) (list 'Wah 1)
     (list 'boom 1) (list 'job 2) (list 'na 16) (list 'yip 9)))
  (define coding-tree (generate-huffman-tree pairs))
  (show #t  "Tree:" (pretty coding-tree) "\n")
  (define song '(
		     Get a job
		     Sha na na na na na na na na
		     Get a job
		     Sha na na na na na na na na
		     Wah yip yip yip yip yip yip yip yip yip
		     Sha boom
		     ))
  (define encoded-song (encode song coding-tree))
  (show #t encoded-song "\n")
  (show #t (decode encoded-song coding-tree) "\n")
#+end_src

#+RESULTS:
#+begin_example
Tree:((leaf na 16)
      ((leaf yip 9)
       (((leaf Get 2) ((leaf boom 1) (leaf Wah 1) (boom Wah) 2)
                      (Get boom Wah)
                      4)
        (((leaf Sha 1) (leaf job 2) (Sha job) 3) (leaf a 4) (Sha job a) 7)
        (Get boom Wah Sha job a)
        11)
       (yip Get boom Wah Sha job a)
       20)
      (na yip Get boom Wah Sha job a)
      36)

(1 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 0 1 1 0 1 0)
(Get a job Sha na na na na na na na na Get a job Sha na na na na na na na na Wah yip yip yip yip yip yip yip yip yip Sha boom)
#+end_example

*** DONE Exercise 2.71 Huffman tree for frequencies 5 and 10
    CLOSED: [2019-10-10 Thu 19:22]

#+begin_src scheme :exports both :results output
  (define true #t)
  (define false #f)
  <<huffman-base>>
  <<huffman-encode>>
  <<element-of-set>>
  <<huffman-sample-tree>>
  <<huffman-generate-tree>>
  (define pairs 
    (list
     (list 'a 1) (list 'b 2) (list 'c 4) (list 'd 8)))
  (define coding-tree (generate-huffman-tree pairs))
  (show #t  "Tree:" (pretty coding-tree) "\n")

#+end_src 

#+RESULTS:
: Tree:((((leaf a 1) (leaf b 2) (a b) 3) (leaf c 4) (a b c) 7) (leaf d 8)
:                                                              (a b c d)
:                                                              15)
: 

#+begin_src plantuml :exports both :file Exercise-2.71.png 
@startmindmap
skinparam monochrome true
+_ ((((leaf a 1)\n (leaf b 2) (a b) 3)\n (leaf c 4) (a b c) 7)\n (leaf d 8) (a b c d) 15)
++_ (leaf d 8)
++_ (((leaf a 1)\n (leaf b 2) (a b) 3) \n(leaf c 4) (a b c) 7)
+++_ (leaf c 4)
+++_ ((leaf a 1) \n(leaf b 2) (a b) 3)
++++_ (leaf b 2)
++++_ (leaf a 1)
@endmindmap
#+end_src 

#+RESULTS:
[[file:Exercise-2.71.png]]

#+begin_src scheme :exports both :results output
  (define true #t)
  (define false #f)
  <<huffman-base>>
  <<huffman-encode>>
  <<element-of-set>>
  <<huffman-sample-tree>>
  <<huffman-generate-tree>>
  (define pairs 
    (list
     (list 'a 1) (list 'b 2) (list 'c 4) (list 'd 8)
     (list 'e 16) (list 'f 32) (list 'g 64) (list 'h 128) (list 'j 256)))
  (define coding-tree (generate-huffman-tree pairs))
  (show #t  "Tree:" (pretty coding-tree) "\n")

#+end_src 

#+RESULTS:
#+begin_example
Tree:(((((((((leaf a 1) (leaf b 2) (a b) 3) (leaf c 4) (a b c) 7) (leaf d 8)
                                                                  (a b c d)
                                                                  15)
          (leaf e 16)
          (a b c d e)
          31) (leaf f 32)
              (a b c d e f)
              63) (leaf g 64)
                  (a b c d e f g)
                  127) (leaf h 128)
                       (a b c d e f g h)
                       255) (leaf j 256)
                            (a b c d e f g h j)
                            511)

#+end_example

#+begin_src plantuml :exports both :file Exercise-2.71.png 
@startmindmap
skinparam monochrome true
+_ (a b c d e f g h j) 511
++_ (leaf j 256)
++_ (a b c d e f g h) 255
+++_ (leaf h 128)
+++_ (a b c d e f g) 127
++++_ (a b c d e f) 63
++++_ (leaf g 64)
+++++_ (a b c d e) 31
+++++_ (leaf f 32)
++++++_ (a b c d) 15
++++++_ (leaf e 16)
+++++++_ (a b c) 7
+++++++_ (leaf d 8) 
++++++++_ (a b) 3
++++++++_ (leaf c 4)
+++++++++_ (leaf a 1)
+++++++++_ (leaf b 2)
@endmindmap
#+end_src 

#+RESULTS:
[[file:Exercise-2.71.png]]

We can clearly see that if the probabilities decrease exponentially, the
length of the tree is n. So to encode the most frequent symbol we would need
just one bit, and the least frequent would require 8 bit.

*** DONE Exercise 2.72 Huffman order of growth
    CLOSED: [2019-10-10 Thu 20:34]

If we consider Exercise 2.71, we'll see that the amount of elements mentioned
at every level of k the tree is n-k.  Therefore, if we want to encode the most
frequent element, we would need to perform O(n-k) operations on every level
of the tree. Since we would need to eventually reach the bottom-most level,
the total number of operations would be \(\sum_1^n (n-k) = O(n^2)\).

The most frequent element is always on
level 1, so to encode it we would need O(1) operations, and we don't even
need to go through the list.

*** Remark Complex packages

The following several exercises can only be considered "functional"
loosely. 

In this subsection I will copy the source of the two complex packages given
as examples.

#+begin_src scheme :exports both :results output
     (define (install-rectangular-package)
       ;; internal procedures
       (define (real-part z) (car z))
       (define (imag-part z) (cdr z))
       (define (make-from-real-imag x y) (cons x y))
       (define (magnitude z)
         (sqrt (+ (square (real-part z))
                  (square (imag-part z)))))
       (define (angle z)
         (atan (imag-part z) (real-part z)))
       (define (make-from-mag-ang r a)
         (cons (* r (cos a)) (* r (sin a))))

       ;; interface to the rest of the system
       (define (tag x) (attach-tag 'rectangular x))
       (put 'real-part '(rectangular) real-part)
       (put 'imag-part '(rectangular) imag-part)
       (put 'magnitude '(rectangular) magnitude)
       (put 'angle '(rectangular) angle)
       (put 'make-from-real-imag 'rectangular
            (lambda (x y) (tag (make-from-real-imag x y))))
       (put 'make-from-mag-ang 'rectangular
            (lambda (r a) (tag (make-from-mag-ang r a))))
       'done)

#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
     (define (install-polar-package)
       ;; internal procedures
       (define (magnitude z) (car z))
       (define (angle z) (cdr z))
       (define (make-from-mag-ang r a) (cons r a))
       (define (real-part z)
         (* (magnitude z) (cos (angle z))))
       (define (imag-part z)
         (* (magnitude z) (sin (angle z))))
       (define (make-from-real-imag x y)
         (cons (sqrt (+ (square x) (square y)))
               (atan y x)))

       ;; interface to the rest of the system
       (define (tag x) (attach-tag 'polar x))
       (put 'real-part '(polar) real-part)
       (put 'imag-part '(polar) imag-part)
       (put 'magnitude '(polar) magnitude)
       (put 'angle '(polar) angle)
       (put 'make-from-real-imag 'polar
            (lambda (x y) (tag (make-from-real-imag x y))))
       (put 'make-from-mag-ang 'polar
            (lambda (r a) (tag (make-from-mag-ang r a))))
       'done)
#+end_src

#+RESULTS:

*** Remark Reference to the put and get functions
~put~ and ~get~ functions are defined later, however, you can use them if
tangling in the block called: <<put-and-get>>. It is a stateful block, so be
sure to include it first.
*** DONE Exercise 2.73 data-driven-deriv
    CLOSED: [2019-10-11 Fri 11:05]

#+begin_src scheme :exports both :results output :noweb-ref data-driven-deriv
          (define (deriv exp var)
             (cond ((number? exp) 0)
                   ((variable? exp) (if (same-variable? exp var) 1 0))
                   (else ((get 'deriv (operator exp)) (operands exp)
                                                      var))))
          (define (operator exp) (car exp))
          (define (operands exp) (cdr exp))
#+end_src

**** DONE a
     CLOSED: [2019-10-11 Fri 10:29]
 We replaced the fixed ~product?~ and ~sum?~ predicate functions with the
ones dispatched on the table. Both of these predicates require their tested
variable to be a ~cons~. This is why ~number?~ and ~variable?~ cannot be
replaced with a dispatched version − they are not a pair.

**** DONE b
Surprise-surprise, the prototype of the two ~deriv~ functions we are
supposed to write is incompatible with the derivatives we had to write in the Exercise-2.56.

#+begin_src scheme :exports both :results output :noweb-ref data-driven-sum-mul
  (define (differentiate-sum operands var)
    (make-sum (deriv (car  operands) var)
	      (deriv (cadr operands) var)))
  (define (differentiate-multiplication operands var)
    (make-sum
     (make-product (car  operands)
		   (deriv (cadr operands) var))
     (make-product (deriv (car  operands) var)
		   (cadr operands))))
  (put 'deriv '+ differentiate-sum)
  (put 'deriv '* differentiate-multiplication)
#+end_src

#+begin_src scheme :exports both :results output
<<put-and-get>>
<<deriv-components>>
<<deriv-operations>>
<<data-driven-deriv>>
<<data-driven-sum-mul>>
(show #t "Test:" (deriv '(+ a (* b a)) 'a) "\n")
#+end_src

#+RESULTS:
: Test:(+ 1 b)

**** DONE c
     CLOSED: [2019-10-11 Fri 11:03]

#+begin_src scheme :exports both :results output :noweb-ref data-driven-exponentiation
(define (make-exponentiation base power)
    (cond ((=number? power 0) 1)
	  ((=number? power 1) base)
	  ((and (number? base) (number? power))
	   (expt base power))
	  (else (list '** base power))))

(define (differentiate-exponentiation exp var)
	   (make-product (cadr exp)
			 (make-product
			  (make-exponentiation
			   (car exp)
			   (make-sum (cadr exp) -1))
			  (deriv (car exp) var))))

(put 'deriv '** differentiate-exponentiation)
#+end_src

#+begin_src scheme :exports both :results output
(define false #f)
<<put-and-get>>
<<deriv-components>>
<<deriv-operations>>
<<data-driven-deriv>>
<<data-driven-sum-mul>>
<<data-driven-exponentiation>>
(show #t "Test:" (deriv '(+ a (* b (** a c))) 'a) "\n")

#;(show #t "Test:" (deriv '(** a b) 'a) "\n")
#+end_src

#+RESULTS:
: Test:(+ 1 (* b (* c (** a (+ c -1)))))

**** DONE d
     CLOSED: [2019-10-11 Fri 11:05]

The only change needed is to change the order of parameters in ~put~ just as
it is changed in ~get~. The rest should be absolutely the same.

*** DONE Exercise 2.74 Insatiable Enterprises
    CLOSED: [2019-10-11 Fri 20:56]

This task is a bit weird and too vaguely formulated. For the start, let's
assume that the company only has two divisions.

#+begin_src scheme :exports both :results output :noweb-ref insatiable-enterprises-data
  (define division-1-set-of-records
     (cons 'division-1 (list (list 'Jack (cons 'salary 100) (cons 'address #f)) (list 'Jill (cons 'salary 200) '(address #t)))))
  (define (division-1-get-record record-set key)
    (define (crawler records key)
      (cond ((null? records) '())
	    ((eq? key (caar records)) (car records))
	    (else (crawler (cdr records) key))))
    (crawler (cdr record-set) key))

  (define (division-1-get-salary record)
     (cdr (list-ref record 1)))

  (define division-2-set-of-records
    (cons 'division-2 (list (list 'placeholder 'WangYi 'salary 100 'address 'neverland) (list 'placeholder 'ZhangEr 'salary 200 'address 'this-world))))

  (define (division-2-get-record record-set key)
    (define (crawler records key)
      (cond ((null? records) '())
	    ((eq? key (list-ref (car records) 1)) (car records))
	    (else (crawler (cdr records) key))))
    (crawler (cdr record-set) key))
  (define (division-2-get-salary record)
     (list-ref record 3))

(put 'get-record 'division-1 division-1-get-record)
(put 'get-record 'division-2 division-2-get-record)
(put 'get-salary 'division-1 division-1-get-salary)
(put 'get-salary 'division-2 division-2-get-salary)



#+end_src

#+begin_src scheme :exports both :results output
<<put-and-get>>
<<insatiable-enterprises-data>>

(show #t "Division-1: " (division-1-get-record division-1-set-of-records 'Jack) "\n")
(show #t "Division-2: " (division-2-get-record division-2-set-of-records 'WangYi) "\n")
(show #t "Division-2: " (division-2-get-record division-2-set-of-records 'ZhangEr) "\n")
(show #t "Salary-1:   " (division-1-get-salary (division-1-get-record division-1-set-of-records 'Jill)) "\n")
(show #t "Salary-2:   " (division-2-get-salary (division-2-get-record division-2-set-of-records 'WangYi)) "\n")
(show #t "Division-1: " ((get 'get-record 'division-1) division-1-set-of-records 'Jack) "\n")
(show #t "Division-2: " ((get 'get-record 'division-2) division-2-set-of-records 'WangYi) "\n")
(show #t "Division-1: " ((get 'get-salary 'division-1) (division-1-get-record division-1-set-of-records 'Jill)) "\n")
(show #t "Division-2: " ((get 'get-salary 'division-2) (division-2-get-record division-2-set-of-records 'WangYi)) "\n")

#+end_src

#+RESULTS:
: Division-1: (Jack (salary . 100) (address . #f))
: Division-2: (placeholder WangYi salary 100 address neverland)
: Division-2: (placeholder ZhangEr salary 200 address this-world)
: Salary-1:   200
: Salary-2:   100
: Division-1: (Jack (salary . 100) (address . #f))
: Division-2: (placeholder WangYi salary 100 address neverland)
: Division-1: 200
: Division-2: 100

**** DONE a
     CLOSED: [2019-10-11 Fri 18:39]

The key thing in our implementation of the two datasets is that we have a
department tag at the beginning. This lets us dispatch on the origin of the
data.

#+begin_src scheme :exports both :results output :noweb-ref insatiable-a
(define (get-record dataset key)
   ((get 'get-record (car dataset)) dataset key))
#+end_src

#+begin_src scheme :exports both :results output
<<put-and-get>>
<<insatiable-enterprises-data>>
<<insatiable-a>>

(show #t (get-record division-1-set-of-records 'Jill) "\n")
(show #t (get-record division-2-set-of-records 'ZhangEr) "\n")
#+end_src

#+RESULTS:
: (Jill (salary 200) (address #t))
: (placeholder ZhangEr salary 200 address this-world)

**** DONE b
     CLOSED: [2019-10-11 Fri 20:22]

#+begin_src scheme :exports both :results output :noweb-ref insatiable-b
  (define (get-salary records key)
    (let ((record (get-record records key)))
      (if record
	  ((get 'get-salary (car records)) record)
	  #f)))
#+end_src

#+RESULTS:


#+begin_src scheme :exports both :results output
<<put-and-get>>
<<insatiable-enterprises-data>>
<<insatiable-a>>
<<insatiable-b>>
(show #t "Salary wrong  : " (get-salary division-2-set-of-records 'Jill) "\n")
(show #t "Salary correct: " (get-salary division-1-set-of-records 'Jill) "\n")
#+end_src

#+RESULTS:
: Salary wrong  : #f
: Salary correct: 200

Because all the dispatch is organized on a tag in the file records, there is
no specific requirements to the record structure.

**** DONE c
     CLOSED: [2019-10-11 Fri 20:54]

#+begin_src scheme :exports both :results output :noweb-ref insatiable-find-employee-record
    <<accumulate>>
      (define (find-employee-record key . record-files)
	(car (accumulate
	      append
	      '()
	      (map (lambda (x)
		     (list (get-record x key))) record-files))))
#+end_src

#+begin_src scheme :exports both :results output
<<put-and-get>>
<<insatiable-enterprises-data>>
<<insatiable-a>>
<<insatiable-b>>
<<insatiable-find-employee-record>>
(show #t "Result: " (find-employee-record 'Jill division-1-set-of-records division-2-set-of-records) "\n")
#+end_src

#+RESULTS:
: Result: (Jill (salary . 200) (address #t))

**** DONE d
     CLOSED: [2019-10-11 Fri 20:56]
The new company would need to prepend their files with ~('companyname)~, and
their functions ~get-record~ and ~get-salary~ need to be registered with the
new the function table.

*** DONE Exercise 2.75 make-from-mag-ang message passing
    CLOSED: [2019-10-11 Fri 21:24]

#+begin_src scheme :exports both :results output :noweb-ref message-mag-angle
     (define (make-from-mag-angle mag angle)
       (define (dispatch op)
         (cond ((eq? op 'real-part) (* mag (cos angle)))
               ((eq? op 'imag-part) (* mag (sin angle)))
               ((eq? op 'magnitude) mag)
               ((eq? op 'angle) angle)
               (else
                (error "Unknown op -- MAKE-FROM-REAL-IMAG" op))))
       dispatch)
#+end_src

#+begin_src scheme :exports both :results output
<<message-mag-angle>>
(show #t "Magnitude: " ((make-from-mag-angle 1 1) 'magnitude) "\n")
(show #t "Angle    : " ((make-from-mag-angle 1 1) 'angle    ) "\n")
(show #t "Real-part: " ((make-from-mag-angle 1 1) 'real-part) "\n")
(show #t "Imag-part: " ((make-from-mag-angle 1 1) 'imag-part) "\n")
#+end_src

#+RESULTS:
: Magnitude: 1
: Angle    : 1
: Real-part: 0.5403023058681398
: Imag-part: 0.8414709848078965

*** DONE Exercise 2.76 types or functions?
    CLOSED: [2019-10-11 Fri 21:29]

Dispatching on the types seems more appropriate for the case when there are
more operations that types. This way there is no need to adjust types when
new operations are created. Just add new operations to the table.

The message-passing style seems more appropriate for the situations when
new operations are relatively rare, but new types appear often. Existing
operations would work with the new types, if the types satisfy some contract.

*** Remark Three arithmetic packages
#+begin_src scheme :exports both :results output :noweb-ref generic-arithmetic-packages
     (define (add x y) (apply-generic 'add x y))
     (define (sub x y) (apply-generic 'sub x y))
     (define (mul x y) (apply-generic 'mul x y))
     (define (div x y) (apply-generic 'div x y))

     (define (install-scheme-number-package)
       (define (tag x)
         (attach-tag 'scheme-number x))
       (put 'add '(scheme-number scheme-number)
            (lambda (x y) (tag (+ x y))))
       (put 'sub '(scheme-number scheme-number)
            (lambda (x y) (tag (- x y))))
       (put 'mul '(scheme-number scheme-number)
            (lambda (x y) (tag (* x y))))
       (put 'div '(scheme-number scheme-number)
            (lambda (x y) (tag (/ x y))))
       (put 'make 'scheme-number
            (lambda (x) (tag x)))
       'done)

     (define (make-scheme-number n)
       ((get 'make 'scheme-number) n))

     (define (install-rational-package)
       (define (numer x) (car x))
       (define (denom x) (cdr x))
       (define (make-rat n d)
         (let ((g (gcd n d)))
           (cons (/ n g) (/ d g))))
       (define (add-rat x y)
         (make-rat (+ (* (numer x) (denom y))
                      (* (numer y) (denom x)))
                   (* (denom x) (denom y))))
       (define (sub-rat x y)
         (make-rat (- (* (numer x) (denom y))
                      (* (numer y) (denom x)))
                   (* (denom x) (denom y))))
       (define (mul-rat x y)
         (make-rat (* (numer x) (numer y))
                   (* (denom x) (denom y))))
       (define (div-rat x y)
         (make-rat (* (numer x) (denom y))
                   (* (denom x) (numer y))))

       (define (tag x) (attach-tag 'rational x))
       (put 'add '(rational rational)
            (lambda (x y) (tag (add-rat x y))))
       (put 'sub '(rational rational)
            (lambda (x y) (tag (sub-rat x y))))
       (put 'mul '(rational rational)
            (lambda (x y) (tag (mul-rat x y))))
       (put 'div '(rational rational)
            (lambda (x y) (tag (div-rat x y))))

       (put 'make 'rational
            (lambda (n d) (tag (make-rat n d))))
       'done)

     (define (make-rational n d)
       ((get 'make 'rational) n d))

     (define (install-rectangular-package)

       (define (real-part z) (car z))
       (define (imag-part z) (cdr z))
       (define (make-from-real-imag x y) (cons x y))
       (define (magnitude z)
         (sqrt (+ (square (real-part z))
                  (square (imag-part z)))))
       (define (angle z)
         (atan (imag-part z) (real-part z)))
       (define (make-from-mag-ang r a)
         (cons (* r (cos a)) (* r (sin a))))

       (define (tag x) (attach-tag 'rectangular x))
       (put 'real-part '(rectangular) real-part)
       (put 'imag-part '(rectangular) imag-part)
       (put 'magnitude '(rectangular) magnitude)
       (put 'angle '(rectangular) angle)
       (put 'make-from-real-imag 'rectangular
            (lambda (x y) (tag (make-from-real-imag x y))))
       (put 'make-from-mag-ang 'rectangular
            (lambda (r a) (tag (make-from-mag-ang r a))))
       'done)

     (define (install-polar-package)

       (define (magnitude z) (car z))
       (define (angle z) (cdr z))
       (define (make-from-mag-ang r a) (cons r a))
       (define (real-part z)
         (* (magnitude z) (cos (angle z))))
       (define (imag-part z)
         (* (magnitude z) (sin (angle z))))
       (define (make-from-real-imag x y)
         (cons (sqrt (+ (square x) (square y)))
               (atan y x)))

       (define (tag x) (attach-tag 'polar x))
       (put 'real-part '(polar) real-part)
       (put 'imag-part '(polar) imag-part)
       (put 'magnitude '(polar) magnitude)
       (put 'angle '(polar) angle)
       (put 'make-from-real-imag 'polar
            (lambda (x y) (tag (make-from-real-imag x y))))
       (put 'make-from-mag-ang 'polar
            (lambda (r a) (tag (make-from-mag-ang r a))))
       'done)

     (define (install-complex-package)
       (define (make-from-real-imag x y)
         ((get 'make-from-real-imag 'rectangular) x y))
       (define (make-from-mag-ang r a)
         ((get 'make-from-mag-ang 'polar) r a))
       (define (add-complex z1 z2)
         (make-from-real-imag (+ (real-part z1) (real-part z2))
                              (+ (imag-part z1) (imag-part z2))))
       (define (sub-complex z1 z2)
         (make-from-real-imag (- (real-part z1) (real-part z2))
                              (- (imag-part z1) (imag-part z2))))
       (define (mul-complex z1 z2)
         (make-from-mag-ang (* (magnitude z1) (magnitude z2))
                            (+ (angle z1) (angle z2))))
       (define (div-complex z1 z2)
         (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
                            (- (angle z1) (angle z2))))
       (define (tag z) (attach-tag 'complex z))
       (put 'add '(complex complex)
            (lambda (z1 z2) (tag (add-complex z1 z2))))
       (put 'sub '(complex complex)
            (lambda (z1 z2) (tag (sub-complex z1 z2))))
       (put 'mul '(complex complex)
            (lambda (z1 z2) (tag (mul-complex z1 z2))))
       (put 'div '(complex complex)
            (lambda (z1 z2) (tag (div-complex z1 z2))))
       (put 'make-from-real-imag 'complex
            (lambda (x y) (tag (make-from-real-imag x y))))
       (put 'make-from-mag-ang 'complex
            (lambda (r a) (tag (make-from-mag-ang r a))))
       'done)

     (define (make-complex-from-real-imag x y)
       ((get 'make-from-real-imag 'complex) x y))

     (define (make-complex-from-mag-ang r a)
       ((get 'make-from-mag-ang 'complex) r a))


#+end_src

#+RESULTS:


#+begin_src scheme :exports both :results output :noweb-ref apply-generic
     (define (attach-tag type-tag contents)
       (cons type-tag contents))

     (define (type-tag datum)
       (if (pair? datum)
           (car datum)
           (error "Bad tagged datum -- TYPE-TAG" datum)))

     (define (contents datum)
       (if (pair? datum)
           (cdr datum)
           (error "Bad tagged datum -- CONTENTS" datum)))

     (define (rectangular? z)
       (eq? (type-tag z) 'rectangular))

     (define (polar? z)
       (eq? (type-tag z) 'polar))

     (define (apply-generic op . args)
       (let ((type-tags (map type-tag args)))
         (let ((proc (get op type-tags)))
           (if proc
               (apply proc (map contents args))
               (error
                 "No method for these types -- APPLY-GENERIC"
                 (list op type-tags))))))

     (define (real-part z) (apply-generic 'real-part z))
     (define (imag-part z) (apply-generic 'imag-part z))
     (define (magnitude z) (apply-generic 'magnitude z))
     (define (angle z) (apply-generic 'angle z))

#+end_src

*** DONE Exercise 2.77 generic-algebra-magnitude
    CLOSED: [2019-10-12 Sat 16:01]
Yeah, great, Dr. Abelson. You're casually referring to the ~apply-generic~,
not really specifying which one to use. Also, I never had to use the
~type-tag~ and ~contents~, which suddenly appear here.

#+begin_src scheme :exports both :results output :noweb-ref alyssa-complex-suggestion
          (put 'real-part '(complex) real-part)
          (put 'imag-part '(complex) imag-part)
          (put 'magnitude '(complex) magnitude)
          (put 'angle '(complex) angle)
#+end_src

#+begin_src scheme :exports both :results output
(define false #f)
(define true  #t)
<<put-and-get>>
<<apply-generic>>

<<generic-arithmetic-packages>>

(install-rectangular-package)
(install-complex-package)

<<alyssa-complex-suggestion>>

(show #t "Louis's result: " (magnitude (make-complex-from-real-imag 3 4)) "\n")

#+end_src

#+RESULTS:
: Louis's result: 5

This example illustrates what can, perhaps, be called "double
dispatch". Indeed,  our "complex" implementation still keeps the 'rectangular
and 'polar tags, so the only thing that the complex ~magnitude~ should do is
to call (through the dispatch table) the old function ~magnitude~, which
will, by itself, dispatch on the old tags. ~apply-generic~ is called twice,
first for a 'complex tag, an later for the 'polar tag. 

Remark: this "easy" exercise took more than 4 hours to debug and consists of
227 lines of code.

*** DONE Exercise 2.78 Ordinary numbers for scheme
    CLOSED: [2019-10-12 Sat 21:06]

#+begin_src scheme :exports both :results output :noweb-ref simplified-scheme-number
     (define (add x y) (apply-generic 'add x y))
     (define (sub x y) (apply-generic 'sub x y))
     (define (mul x y) (apply-generic 'mul x y))
     (define (div x y) (apply-generic 'div x y))
     (define (attach-tag type-tag contents)
       (if (eq? type-tag 'scheme-number)
           contents
           (cons type-tag contents)))

     (define (type-tag datum)
       (cond ((pair? datum) (car datum))
             ((number? datum) 'scheme-number)
             (else (error "Bad tagged datum -- TYPE-TAG" datum))))

     (define (contents datum)
       (cond ((pair? datum) (cdr datum))
             ((number? datum) datum)
             (else (error "Bad tagged datum -- CONTENTS" datum))))

     (define (apply-generic op . args)
       (let ((type-tags (map type-tag args)))
         (let ((proc (get op type-tags)))
           (if proc
               (apply proc (map contents args))
               (error
                 "No method for these types -- APPLY-GENERIC"
                 (list op type-tags))))))

     (define (install-scheme-number-package)
       (define (tag x)
         (attach-tag 'scheme-number x))
       (put 'add '(scheme-number scheme-number)
            (lambda (x y) (tag (+ x y))))
       (put 'sub '(scheme-number scheme-number)
            (lambda (x y) (tag (- x y))))
       (put 'mul '(scheme-number scheme-number)
            (lambda (x y) (tag (* x y))))
       (put 'div '(scheme-number scheme-number)
            (lambda (x y) (tag (/ x y))))
       (put 'make 'scheme-number
            (lambda (x) (tag x)))
       'done)

     (define (make-scheme-number n)
       ((get 'make 'scheme-number) n))
#+end_src

#+begin_src scheme :exports both :results output
<<put-and-get>>
<<simplified-scheme-number>>
(install-scheme-number-package)
(show #t "Adding: (+ 1 2) : " (add (make-scheme-number 1) (make-scheme-number 2)) "\n")
#+end_src

#+RESULTS:
: Adding: (+ 1 2) : 3

The task is to "Modify the definitions of `type-tag', `contents', and
`attach-tag'", therefore (as this doesn't seem really useful), I am only
copying those functions for modification in this particular exercise.

*** DONE Exercise 2.79 generic-equality
    CLOSED: [2019-10-14 Mon 15:58]

In this exercise I am copying the whole package again, as due to the poor
architecture of the algebra system, adding such a tiny feature is not additive.

#+begin_src scheme :exports both :results output

  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))
  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (if (pair? datum)
	(car datum)
	(error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (if (pair? datum)
	(cdr datum)
	(error "Bad tagged datum -- CONTENTS" datum)))

  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))

  (define (apply-generic op . args)
    (let ((type-tags (map type-tag args)))
      (let ((proc (get op type-tags)))
	(if proc
	    (apply proc (map contents args))
	    (error
	      "No method for these types -- APPLY-GENERIC"
	      (list op type-tags))))))

  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))
   
  (define (equ? x y) (apply-generic 'equ? x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
         (lambda (x y) (= x y)))
    'done)

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
         (lambda (x y) (= 0 (numer (sub-rat x y)))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (sqrt (+ (square (real-part z))
	       (square (imag-part z)))))
    (define (angle z)
      (atan (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (* r (cos a)) (* r (sin a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (* (magnitude z) (cos (angle z))))
    (define (imag-part z)
      (* (magnitude z) (sin (angle z))))
    (define (make-from-real-imag x y)
      (cons (sqrt (+ (square x) (square y)))
	    (atan y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (+ (real-part z1) (real-part z2))
			   (+ (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (- (real-part z1) (real-part z2))
			   (- (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (* (magnitude z1) (magnitude z2))
			 (+ (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
			 (- (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
         (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
                      (= 0 (imag-part (sub-complex x y))))))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))



  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

  (show #t "Scheme-number: " (equ? (make-scheme-number 1) (make-scheme-number 2)) "\n")
  (show #t "Rational: " (equ? (make-rational 1 2) (make-rational 2 4)) "\n")
  (show #t "Complex: " (equ? (make-complex-from-mag-ang 1 0)
                             (make-complex-from-real-imag 1 0)) "\n")
#+end_src

#+RESULTS:
: Scheme-number: #f
: Rational: #t
: Complex: #t

*** DONE Exercise 2.80 Generic arithmetic zero?
    CLOSED: [2019-10-14 Mon 17:18]

#+begin_src scheme :exports both :results output

  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))
  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (if (pair? datum)
	(car datum)
	(error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (if (pair? datum)
	(cdr datum)
	(error "Bad tagged datum -- CONTENTS" datum)))

  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))

  (define (apply-generic op . args)
    (let ((type-tags (map type-tag args)))
      (let ((proc (get op type-tags)))
	(if proc
	    (apply proc (map contents args))
	    (error
	      "No method for these types -- APPLY-GENERIC"
	      (list op type-tags))))))

  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y) (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	  (lambda (x) (= 0 x)))
    'done)

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (sqrt (+ (square (real-part z))
	       (square (imag-part z)))))
    (define (angle z)
      (atan (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (* r (cos a)) (* r (sin a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (* (magnitude z) (cos (angle z))))
    (define (imag-part z)
      (* (magnitude z) (sin (angle z))))
    (define (make-from-real-imag x y)
      (cons (sqrt (+ (square x) (square y)))
	    (atan y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (+ (real-part z1) (real-part z2))
			   (+ (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (- (real-part z1) (real-part z2))
			   (- (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (* (magnitude z1) (magnitude z2))
			 (+ (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
			 (- (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
		      (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))



  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

  (show #t "Scheme-number: " (zero? (make-scheme-number 0)) "\n")
  (show #t "Rational: " (zero? (make-rational 0 2)) "\n")
  (show #t "Complex: " (zero? (make-complex-from-mag-ang 0 0)) "\n")
#+end_src

#+RESULTS:
: Scheme-number: #t
: Rational: #t
: Complex: #t

*** Snippet put-coercion
I added the ~put-coercion~ and ~get-coercion~ procedures to the
<<put-and-get>> noweb fragment. This doesn't seem to be much of a problem,
because these operations are not used before this point.
*** Snippet coercion procedures

We are modifying ~apply-generic~ in this snippet, which means that we may
need to do a lot of copying of the old code in order to make it work with the
new code.

#+begin_src scheme :exports both :results output :noweb-ref coercion-procedures-apply-generic
  (define (scheme-number->complex n)
    (make-complex-from-real-imag (contents n) 0))
  (put-coercion 'scheme-number
		'complex
		scheme-number->complex)

  (define (apply-generic op . args)
    (let ((type-tags (map type-tag args)))
      (let ((proc (get op type-tags)))
	(if proc
	    (apply proc (map contents args))
	    (if (= (length args) 2)
		(let ((type1 (car type-tags))
		      (type2 (cadr type-tags))
		      (a1 (car args))
		      (a2 (cadr args)))
		  (let ((t1->t2 (get-coercion type1 type2))
			(t2->t1 (get-coercion type2 type1)))
		    (cond (t1->t2
			   (apply-generic op (t1->t2 a1) a2))
			  (t2->t1
			   (apply-generic op a1 (t2->t1 a2)))
			  (else
			   (error "No method for these types"
				  (list op type-tags))))))
		(error "No method for these types"
		       (list op type-tags)))))))


#+end_src

#+RESULTS:
: Exception: {Exception #19 user "undefined variable" (put-coercion) #<procedure #f> (#f . 4)}

*** DONE Exercise 2.81 coercion to-itself
    CLOSED: [2019-10-15 Tue 11:16]
Another extremely ill-defined problem.
Let us try to do some mind-reading to understand which parts of code we need
to tangle to solve it letter by letter.

**** a

I will tangle in the version of the algebra package from the Exercise-2.80,
but I will replace the ~apply-generic~ with a coercing version.

#+begin_src scheme :exports both :results output
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (if (pair? datum)
	(car datum)
	(error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (if (pair? datum)
	(cdr datum)
	(error "Bad tagged datum -- CONTENTS" datum)))

  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))

  (define (apply-generic op . args)
    (let ((type-tags (map type-tag args)))
	 (let ((proc (get op type-tags)))
	   (if proc
	       (apply proc (map contents args))
	       (if (= (length args) 2)
		   (let ((type1 (car type-tags))
			 (type2 (cadr type-tags))
			 (a1 (car args))
			 (a2 (cadr args)))
		     (let ((t1->t2 (get-coercion type1 type2))
			   (t2->t1 (get-coercion type2 type1)))
		       (cond (t1->t2
			      (apply-generic op (t1->t2 a1) a2))
			     (t2->t1
			      (apply-generic op a1 (t2->t1 a2)))
			     (else
			      (error "No method for these types"
				     (list op type-tags))))))
		   (error "No method for these types"
			  (list op type-tags)))))))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y) (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	  (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	  (lambda (x y) (tag (expt x y))))

    'done)

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (sqrt (+ (square (real-part z))
	       (square (imag-part z)))))
    (define (angle z)
      (atan (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (* r (cos a)) (* r (sin a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (* (magnitude z) (cos (angle z))))
    (define (imag-part z)
      (* (magnitude z) (sin (angle z))))
    (define (make-from-real-imag x y)
      (cons (sqrt (+ (square x) (square y)))
	    (atan y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (+ (real-part z1) (real-part z2))
			   (+ (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (- (real-part z1) (real-part z2))
			   (- (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (* (magnitude z1) (magnitude z2))
			 (+ (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
			 (- (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
		      (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))



  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

  (define (scheme-number->scheme-number n) n)
  (define (complex->complex z) z)
  (put-coercion 'scheme-number 'scheme-number
                 scheme-number->scheme-number)
  (put-coercion 'complex 'complex complex->complex)

(show #t (displayed (exp (make-complex-from-mag-ang 2 0) (make-complex-from-mag-ang 2 0))))

#+end_src

#+RESULTS:
: Geiser-eval--retort-output returned nil.
: The interpreter produced no output
: or there is a bug in geiser (likely!)

We can see that this code doesn't work as expected. Why? 
The answer is because the new version of ~apply-generic~ only checks if the
coercions exist, not whether the function on the new coerced types exists.

This seems like making sense, as in order to "find a common denominator",
more than one coercion may be needed, but the result is not good in the sense
that if the final function doesn't exist, ~apply-generic~ ends up applying
itself over and over. So the strategy proposed by Louis is not very good.

**** b

#+begin_src scheme :exports both :results output
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (if (pair? datum)
	(car datum)
	(error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (if (pair? datum)
	(cdr datum)
	(error "Bad tagged datum -- CONTENTS" datum)))

  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))

  (define (apply-generic op . args)
    (let ((type-tags (map type-tag args)))
	 (let ((proc (get op type-tags)))
	   (if proc
	       (apply proc (map contents args))
	       (if (= (length args) 2)
		   (let ((type1 (car type-tags))
			 (type2 (cadr type-tags))
			 (a1 (car args))
			 (a2 (cadr args)))
		     (let ((t1->t2 (get-coercion type1 type2))
			   (t2->t1 (get-coercion type2 type1)))
		       (cond (t1->t2
			      (apply-generic op (t1->t2 a1) a2))
			     (t2->t1
			      (apply-generic op a1 (t2->t1 a2)))
			     (else
			      (error "No method for these types"
				     (list op type-tags))))))
		   (error "No method for these types"
			  (list op type-tags)))))))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y) (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	  (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	  (lambda (x y) (tag (expt x y))))

    'done)

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (sqrt (+ (square (real-part z))
	       (square (imag-part z)))))
    (define (angle z)
      (atan (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (* r (cos a)) (* r (sin a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (* (magnitude z) (cos (angle z))))
    (define (imag-part z)
      (* (magnitude z) (sin (angle z))))
    (define (make-from-real-imag x y)
      (cons (sqrt (+ (square x) (square y)))
	    (atan y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (+ (real-part z1) (real-part z2))
			   (+ (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (- (real-part z1) (real-part z2))
			   (- (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (* (magnitude z1) (magnitude z2))
			 (+ (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
			 (- (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
		      (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))



  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

(show #t " " (displayed (exp (make-scheme-number 2) (make-scheme-number 2))) "\n")
(show #t " " (displayed (exp (make-complex-from-mag-ang 2 0) 
                             (make-complex-from-mag-ang 2 0))))
#+end_src

#+RESULTS:
:  (scheme-number . 4)
: Exception: {Exception #19 user "No method for these types" ((exp (complex complex))) #f #f}

This seems correct. There may be a problem when the function is actually
defined for some types that the given ones are coerce-able to, but the system
doesn't try that.

**** c

#+begin_src scheme :exports both :results output
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (if (pair? datum)
	(car datum)
	(error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (if (pair? datum)
	(cdr datum)
	(error "Bad tagged datum -- CONTENTS" datum)))

  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))

  (define (apply-generic op . args)
    (let ((type-tags (map type-tag args)))
	 (let ((proc (get op type-tags)))
	   (if proc
	       (apply proc (map contents args))
	       (if (and (= (length args) 2) (not (eq? (car type-tags) (cadr type-tags))))
		   (let ((type1 (car type-tags))
			 (type2 (cadr type-tags))
			 (a1 (car args))
			 (a2 (cadr args)))
		     (let ((t1->t2 (get-coercion type1 type2))
			   (t2->t1 (get-coercion type2 type1)))
		       (cond (t1->t2
			      (apply-generic op (t1->t2 a1) a2))
			     (t2->t1
			      (apply-generic op a1 (t2->t1 a2)))
			     (else
			      (error "No method for these types"
				     (list op type-tags))))))
		   (error "No method for these types"
			  (list op type-tags)))))))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y) (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	  (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	  (lambda (x y) (tag (expt x y))))

    'done)

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (sqrt (+ (square (real-part z))
	       (square (imag-part z)))))
    (define (angle z)
      (atan (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (* r (cos a)) (* r (sin a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (* (magnitude z) (cos (angle z))))
    (define (imag-part z)
      (* (magnitude z) (sin (angle z))))
    (define (make-from-real-imag x y)
      (cons (sqrt (+ (square x) (square y)))
	    (atan y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (+ (real-part z1) (real-part z2))
			   (+ (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (- (real-part z1) (real-part z2))
			   (- (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (* (magnitude z1) (magnitude z2))
			 (+ (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
			 (- (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
		      (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))



  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

(show #t " " (displayed (exp (make-scheme-number 2) (make-scheme-number 2))))


#+end_src

#+RESULTS:
:  (scheme-number . 4)

*** DONE Exercise 2.82 three-argument-coercion
    CLOSED: [2019-10-15 Tue 21:40]
I am copying the whole "algebra" mess, because I already lost track of which
functions are needed for the tests to work. Bad practice, don't do so.

#+begin_src scheme :exports both :results output :noweb-ref generic-arithmetic-packages-multidispatch
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (if (pair? datum)
	(car datum)
	(error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (if (pair? datum)
	(cdr datum)
	(error "Bad tagged datum -- CONTENTS" datum)))

  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y) (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	  (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	  (lambda (x y) (tag (expt x y))))

    'done)

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (sqrt (+ (square (real-part z))
	       (square (imag-part z)))))
    (define (angle z)
      (atan (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (* r (cos a)) (* r (sin a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (* (magnitude z) (cos (angle z))))
    (define (imag-part z)
      (* (magnitude z) (sin (angle z))))
    (define (make-from-real-imag x y)
      (cons (sqrt (+ (square x) (square y)))
	    (atan y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (+ (real-part z1) (real-part z2))
			   (+ (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (- (real-part z1) (real-part z2))
			   (- (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (* (magnitude z1) (magnitude z2))
			 (+ (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
			 (- (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
		      (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))

  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

#+end_src

#+RESULTS:
:  (scheme-number . 4)

#+begin_src scheme :exports both :results output :noweb-ref apply-generic-many-args
  (define (apply-generic op . args)
    (define (all-argtypes-same? . args)
      (let ((type (type-tag (car args))))
	(accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
    (define (coercion-if-exists? type arg-tags)
      (let ((coercion-list (map (lambda (x) 
                             (if (eq? type x)
                                 identity
                                 (get-coercion x type))) arg-tags)))
	(if (accumulate (lambda (x y) (and x y)) #t coercion-list)
	    coercion-list
	    #f)))
    (let ((type-tags (map type-tag args)))
	 (let ((proc (get op type-tags)))
	   (if proc
	       (apply proc (map contents args))
	       (if (and (>= (length args) 2) (not (all-argtypes-same? args)))
		   (let types-loop ((types type-tags))
		     (let ((list-of-coercion-functions
			    (coercion-if-exists? (car types) type-tags)))
		       (if list-of-coercion-functions
			   (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
						  list-of-coercion-functions
						  args)))
		       (if (not (null? (cdr types)))
                           (types-loop (cdr types))
                           (error "Even coercions failed. No method for these types.")))))
		   (error "No method for these types"
			  (list op type-tags)))))))
(define (scheme-number->complex n)
    (make-complex-from-real-imag (contents n) 0))
  (put-coercion 'scheme-number
		'complex
		scheme-number->complex)

(put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
   (max (magnitude z1) (magnitude z2) (magnitude z3))))
(define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
(define (identity x) x)
#+end_src

#+begin_src scheme :exports both :results output
<<accumulate>>
<<generic-arithmetic-packages-multidispatch>>
<<alyssa-complex-suggestion>>
<<apply-generic-many-args>>
(show #t " " (displayed 
               (max3-magnitude 
                  (make-scheme-number 1) 
                  (make-scheme-number 2)
                  (make-complex-from-real-imag 3 0))))
#+end_src

#+RESULTS:
:  3

Well, this solution works, but is not perfect. Indeed, we can promote the
numbers to one of the arguments, but this implementation would fail if the
types are coerce-able, but the operation is not implemented.

*** DONE Exercise 2.83 Numeric Tower and (raise)
    CLOSED: [2019-10-16 Wed 14:53]

This exercise has a problem: the name of the ~(raise)~ function coincides
with the R7RS' built-in name for an operation to raise exceptions. Therefore,
I have to name my operation ~raise-type~.

#+begin_src scheme :exports both :results output
(define numeric-tower (list 'integer 'rational 'scheme-number 'complex))

(define (higher-type x)
   (define (find-higher-type x types)
      (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x))
            ((eq? x (car types)) (cadr types))
            (else (find-higher-type x (cdr types))))))

(define (integer->rational x)
  (make-rational integer 1))

(define (rational->scheme-number x)
  (/ (numer x) (denom x)))
(put-coercion 'integer 'rational integer->rational)
(put-coercion 'rational 'scheme-number rational->scheme-number)

(define (raise-type x) ((get-coercion (type-tag x) (higher-type (type-tag x))) x))

#+end_src

*** DONE Exercise 2.84 Using ~raise~ (~raise-type~) in ~apply-generic~
    CLOSED: [2019-10-17 Thu 11:39]

This exercise is also extremely confusing. Scheme-number, I guess, can
effectively be considered "real", so "rational" numbers should be lower in
the hierarchy than "scheme-number"s. But what about integers? We never had
any operations concerning integers. 

In this exercise I will try to implement the following strategy:
 1. Modify ~type-tag~ to return ~'integer~ for scheme integers.
 2. Will not implement any operations for ~'integer~'s, because those will be
    covered by the ~'rational~ class.

#+begin_src scheme :exports both :results output
  (define (accumulate op initial sequence)
    (if (null? sequence)
	initial
	(accumulate op (op initial (car sequence)) (cdr sequence))))
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (cond ((pair? datum) (car datum))
	  ((exact-integer? datum) 'integer)
	  (error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (cond ((pair? datum) (cdr datum))
	  ((integer? datum) datum)
	  (else (error "Bad tagged datum -- CONTENTS" datum))))

  (define (integer? x)
    (eq? (type-tag x) 'integer))
  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y) (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	 (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	 (lambda (x y) (tag (expt x y))))

    'done)

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    (put 'to-real '(rational) (lambda (x) (/ (numer x) (denom x))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (sqrt (+ (square (real-part z))
	       (square (imag-part z)))))
    (define (angle z)
      (atan (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (* r (cos a)) (* r (sin a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (* (magnitude z) (cos (angle z))))
    (define (imag-part z)
      (* (magnitude z) (sin (angle z))))
    (define (make-from-real-imag x y)
      (cons (sqrt (+ (square x) (square y)))
	    (atan y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (+ (real-part z1) (real-part z2))
			   (+ (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (- (real-part z1) (real-part z2))
			   (- (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (* (magnitude z1) (magnitude z2))
			 (+ (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
			 (- (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
			    (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))

  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

  (put 'real-part '(complex) real-part)
  (put 'imag-part '(complex) imag-part)
  (put 'magnitude '(complex) magnitude)
  (put 'angle '(complex) angle)
  (define (apply-generic op . args)
    (define (all-argtypes-same? . args)
      (let ((type (type-tag (car args))))
	(accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
    (define (coercion-if-exists? type arg-tags)
      (let ((coercion-list (map (lambda (x) 
				  (if (eq? type x)
				      identity
				      (get-coercion x type))) arg-tags)))
	(if (accumulate (lambda (x y) (and x y)) #t coercion-list)
	    coercion-list
	    #f)))
    (let* ((type-tags (map type-tag args))
	   (proc (get op type-tags)))
      (cond (proc (apply proc (map contents args)))
	    ((= 2 (length args))
	     (if (type1<=type2? (car type-tags) (cadr type-tags))
		 (apply-generic op (raise-type (car args)) (cadr args))
		 (apply-generic op (car args)  (raise-type (cadr args)))))
	    ((and (>= (length args) 2) (not (all-argtypes-same? args)))
	     (let types-loop ((types type-tags))
	       (let ((list-of-coercion-functions
		      (coercion-if-exists? (car types) type-tags)))
		 (if list-of-coercion-functions
		     (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
							list-of-coercion-functions
							args)))
		     (if (not (null? (cdr types)))
			 (types-loop (cdr types))
			 (error "Even coercions failed. No method for these types."))))))
	    (else (error "No method for these types"
			 (list op type-tags))))))
  (define (scheme-number->complex n)
    (make-complex-from-real-imag (contents n) 0))
  (put-coercion 'scheme-number
		'complex
		scheme-number->complex)

  (put 'max3-magnitude '(complex complex complex)
       (lambda (z1 z2 z3)
	 (max (magnitude z1) (magnitude z2) (magnitude z3))))
  (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
  (define (identity x) x)

  (define numeric-tower (list 'integer 'rational 'scheme-number 'complex))

  (define (higher-type x)
    (define (find-higher-type x types)
      (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x))
	    ((eq? x (car types)) (cadr types))
	    (else (find-higher-type x (cdr types)))))
    (find-higher-type x numeric-tower))

  (define (type1<=type2? type1 type2)
    (if (not (memq type1 numeric-tower))
	(error "Type 1 not in the numeric tower"))
    (if (not (memq type2 numeric-tower))
	(error "Type 2 not in the numeric tower"))
    (let loop ((types numeric-tower))
      (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
	    ((eq? (car types) type1) #t)
	    ((eq? (car types) type2) #f)
	    (else (loop (cdr types))))))

  (define (integer->rational x)
    (make-rational x 1))

  (define (rational->scheme-number x)
    (make-scheme-number ((get 'to-real 'rational) x)))
  (put-coercion 'integer 'rational integer->rational)
  (put-coercion 'rational 'scheme-number rational->scheme-number)

  (define (raise-type x)
    (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
      (if converter
	  (converter x)
	  (error "No coercion found for x" (type-tag x) x))))


  (define (remainder-integer a b)
    (when (or (not (integer? a)) (not (integer? b)))
      (error "Arguments must be integers" a b))
    (remainder a b))

  (put 'remainder '(integer integer) remainder-integer)
  (define (remainder-generalized a b) (apply-generic 'remainder a b))


  (show #t "Remainder-integer            : " (remainder-generalized 4 2) "\n")
  (show #t "Adding (coercion to rational): " (add 5 6))
#+end_src

#+RESULTS:
: Remainder-integer            : 0
: Adding (coercion to rational): (rational 11 . 1)

This seems to do the job. 

*** DONE Exercise 2.85 Dropping a type 
    CLOSED: [2019-10-20 Sun 13:47]

(I didn't count the time spent on every exercise individually (although it
can be deduced from the total time spent between the CLOSED operations.), but
this exercise took me a lot of time.)

In this exercise I will use the r7rs standard library procedures ~numerator~
and ~denominator~ in order to project numbers from ~'scheme-number~ to
~'rational~. 

Once again, it tangling doesn't help much in dealing with packages, so I will
copy the whole source code again.

In this exercise, I spent quite a lot of time debugging the ~(project)~,
which is how your life in programming will be any way. You spend most of your
time debugging seemingly obvious things and finding bugs in the code you
believed to be working fine. It turns out that I had to fix several bugs in
the coercion functions from the previous exercises. I am not describing those
fixed explicitly, but you may get them by comparing the code.

#+begin_src scheme :exports both :results output
  (define (accumulate op initial sequence)
    (if (null? sequence)
	initial
	(accumulate op (op initial (car sequence)) (cdr sequence))))
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (cond ((pair? datum) (car datum))
	  ((exact-integer? datum) 'integer)
	  (error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (cond ((pair? datum) (cdr datum))
	  ((integer? datum) datum)
	  (else (error "Bad tagged datum -- CONTENTS" datum))))

  (define (integer? x)
    (eq? (type-tag x) 'integer))
  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y)
    (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	 (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	 (lambda (x y) (tag (expt x y))))
    (put 'project '(scheme-number)
	 (lambda (x)
	   (make-rational
	    (exact (numerator x))
	    (exact (denominator x)))))
    'done)

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    (put 'project '(rational) (lambda (x) (exact (truncate (/ (numer x) (denom x))))))
    (put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (sqrt (+ (square (real-part z))
	       (square (imag-part z)))))
    (define (angle z)
      (atan (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (* r (cos a)) (* r (sin a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (* (magnitude z) (cos (angle z))))
    (define (imag-part z)
      (* (magnitude z) (sin (angle z))))
    (define (make-from-real-imag x y)
      (cons (sqrt (+ (square x) (square y)))
	    (atan y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (+ (real-part z1) (real-part z2))
			   (+ (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (- (real-part z1) (real-part z2))
			   (- (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (* (magnitude z1) (magnitude z2))
			 (+ (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (/ (magnitude z1) (magnitude z2))
			 (- (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
			    (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    (put 'project '(complex) (lambda (z) (make-scheme-number (real-part z))))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))

  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

  (put 'real-part '(complex) real-part)
  (put 'imag-part '(complex) imag-part)
  (put 'magnitude '(complex) magnitude)
  (put 'angle '(complex) angle)

  (define (apply-generic op . args)
    (define (all-argtypes-same? . args)
      (let ((type (type-tag (car args))))
	(accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
    (define (coercion-if-exists? type arg-tags)
      (let ((coercion-list (map (lambda (x) 
				  (if (eq? type x)
				      identity
				      (get-coercion x type))) arg-tags)))
	(if (accumulate (lambda (x y) (and x y)) #t coercion-list)
	    coercion-list
	    #f)))
    (drop (let* ((type-tags (map type-tag args))
			 (proc (get op type-tags)))
		    (cond (proc (apply proc (map contents args)))
			  ((= 2 (length args))
			   (if (type1<=type2? (car type-tags) (cadr type-tags))
			       (apply-generic op (raise-type (car args)) (cadr args))
			       (apply-generic op (car args)  (raise-type (cadr args)))))
			  ((and (>= (length args) 2) (not (all-argtypes-same? args)))
			   (let types-loop ((types type-tags))
			     (let ((list-of-coercion-functions
				    (coercion-if-exists? (car types) type-tags)))
			       (if list-of-coercion-functions
				   (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
								      list-of-coercion-functions
								      args)))
				   (if (not (null? (cdr types)))
				       (types-loop (cdr types))
				       (error "apply-generic:Even coercions failed. No method for these types."))))))
			  (else (error "apply-generic:No method for these types"
				       (list op type-tags)))))))
  (define (scheme-number->complex n)
    (make-complex-from-real-imag (contents n) 0))
  (put-coercion 'scheme-number
		'complex
		scheme-number->complex)

  (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
						    (max (magnitude z1) (magnitude z2) (magnitude z3))))
  (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
  (define (identity x) x)

  (define numeric-tower (list 'integer 'rational 'scheme-number 'complex))

  (define (higher-type x)
    (define (find-higher-type x types)
      (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x))
	    ((eq? x (car types)) (cadr types))
	    (else (find-higher-type x (cdr types)))))
    (find-higher-type x numeric-tower))

  (define (type1<=type2? type1 type2)
    (if (not (memq type1 numeric-tower))
	(error "Type 1 not in the numeric tower"))
    (if (not (memq type2 numeric-tower))
	(error "Type 2 not in the numeric tower"))
    (let loop ((types numeric-tower))
      (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
	    ((eq? (car types) type1) #t)
	    ((eq? (car types) type2) #f)
	    (else (loop (cdr types))))))

  (define (integer->rational x)
    (make-rational x 1))

  (define (rational->scheme-number x)
    (make-scheme-number ((get 'to-real '(rational)) x)))
  (put-coercion 'integer 'rational integer->rational)
  (put-coercion 'rational 'scheme-number rational->scheme-number)

  (define (raise-type x)
    (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
      (if converter
	  (converter x)
	  (error "No coercion found for x" (type-tag x) x))))


  (define (remainder-integer a b)
    (when (or (not (integer? a)) (not (integer? b)))
      (error "Arguments must be integers" a b))
    (remainder a b))

  (put 'remainder '(integer integer) remainder-integer)
  (define (remainder-generalized a b) (apply-generic 'remainder a b))

  (define (project obj) (apply-generic 'project obj))
  (define (droppable? obj)
    (cond ((not (memq (type-tag obj) numeric-tower)) #f)
	  ((eq? (type-tag obj) (car numeric-tower)) #f)
	  ((equ? obj (raise-type (project obj))) #t)
	  (else #f)))
  (define (drop obj) 
     (if (droppable? obj)
	 (drop (project obj))
	 obj))

  #;(show #t "Test: " (droppable? (make-complex-from-real-imag 1 0)))
  #;(show #t "Test 2: projecting a 'scheme-number: " (displayed (project (make-scheme-number 1))) "\n")
  #;(show #t "Test 3:" (drop (make-complex-from-real-imag 1 0)) "\n")
  (show #t "Subtracting complex numbers: "
	(sub
	 (make-complex-from-real-imag 1 2)
	 (make-complex-from-real-imag 0 2)) "\n")
   #;(show #t "Dropping #t: " (drop #t) "\n")
   #;(show #t "Dropping #f: " (drop #f) "\n")
   #;(show #t
	"(equ? (raise-type (project '(complex rectangular 1 0))) '(complex rectangular 1 0))" 
	 (equ? (raise-type (project '(complex rectangular 1 0))) '(complex rectangular 1 0)))
    #;(show #t (drop '(complex rectangular 1 0)) "\n")
   #;(show #t "Testing project: " (displayed (project (make-complex-from-real-imag 1 0))) "\n")
   #;(show #t "Testing: " (displayed (equ? (make-complex-from-real-imag 2 0) (raise-type (project (make-complex-from-real-imag 2 1))))) "\n")
#+end_src

#+RESULTS:
: Subtracting complex numbers: 1

*** DONE Exercise 2.86 Compound complex numbers
    CLOSED: [2019-10-20 Sun 20:22]

At the moment, our complex numbers are pairs of two built-in real numbers. We
need to be able to build them from rational and integer numbers too.

Again, since the changes we are doing here are not additive, I will just copy
the whole system in one block.

It seems that implementing sines and cosines over 'scheme-number's is enough,
because the other types should be covered by coercion.

#+begin_src scheme :exports both :results output
    (define (accumulate op initial sequence)
      (if (null? sequence)
	  initial
	  (accumulate op (op initial (car sequence)) (cdr sequence))))
    (define false #f)
    (define true  #t)
    (define (make-table)
      (let ((local-table (list '*table*)))
	(define (lookup key-1 key-2)
	  (let ((subtable (assoc key-1 (cdr local-table))))
	    (if subtable
		(let ((record (assoc key-2 (cdr subtable))))
		  (if record
		      (cdr record)
		      false))
		false)))
	(define (insert! key-1 key-2 value)
	  (let ((subtable (assoc key-1 (cdr local-table))))
	    (if subtable
		(let ((record (assoc key-2 (cdr subtable))))
		  (if record
		      (set-cdr! record value)
		      (set-cdr! subtable
				(cons (cons key-2 value)
				      (cdr subtable)))))
		(set-cdr! local-table
			  (cons (list key-1
				      (cons key-2 value))
				(cdr local-table)))))
	  'ok)
	(define (dispatch m)
	  (cond ((eq? m 'lookup-proc) lookup)
		((eq? m 'insert-proc!) insert!)
		(else (error "Unknown operation -- TABLE" m))))
	dispatch))

    (define operation-table (make-table))
    (define get (operation-table 'lookup-proc))
    (define put (operation-table 'insert-proc!))

    (define coercion-table (make-table))
    (define get-coercion (coercion-table 'lookup-proc))
    (define put-coercion (coercion-table 'insert-proc!))

    (define (attach-tag type-tag contents)
      (cons type-tag contents))

    (define (type-tag datum)
      (cond ((pair? datum) (car datum))
	    ((exact-integer? datum) 'integer)
	    ((real? datum) 'scheme-number)
	    (error "Bad tagged datum -- TYPE-TAG" datum)))

    (define (contents datum)
      (cond ((pair? datum) (cdr datum))
	    ((integer? datum) datum)
	    ((real? datum) datum)
	    (else (error "Bad tagged datum -- CONTENTS" datum))))

    (define (integer? x)
      (eq? (type-tag x) 'integer))
    (define (rectangular? z)
      (eq? (type-tag z) 'rectangular))

    (define (polar? z)
      (eq? (type-tag z) 'polar))


    (define (real-part z) (apply-generic 'real-part z))
    (define (imag-part z) (apply-generic 'imag-part z))
    (define (magnitude z) (apply-generic 'magnitude z))
    (define (angle z) (apply-generic 'angle z))

    (define (add x y) (apply-generic 'add x y))
    (define (sub x y) (apply-generic 'sub x y))
    (define (mul x y) (apply-generic 'mul x y))
    (define (div x y) (apply-generic 'div x y))

    (define (equ? x y)
      (apply-generic 'equ? x y))
    (define (zero? x) (apply-generic 'zero? x))

    (define (exp x y) (apply-generic 'exp x y))

    (define (install-scheme-number-package)
      (define (tag x)
	(attach-tag 'scheme-number x))
      (put 'add '(scheme-number scheme-number)
	   (lambda (x y) (tag (+ x y))))
      (put 'sub '(scheme-number scheme-number)
	   (lambda (x y) (tag (- x y))))
      (put 'mul '(scheme-number scheme-number)
	   (lambda (x y) (tag (* x y))))
      (put 'div '(scheme-number scheme-number)
	   (lambda (x y) (tag (/ x y))))
      (put 'make 'scheme-number
	   (lambda (x) (tag x)))
      (put 'equ? '(scheme-number scheme-number)
	   (lambda (x y) (= x y)))
      (put 'zero? '(scheme-number)
	   (lambda (x) (= 0 x)))
      (put 'exp '(scheme-number scheme-number)
	   (lambda (x y) (tag (expt x y))))
      (put 'project '(scheme-number)
	   (lambda (x)
	     (show #t "Calling project 'scheme-number\n")
	     (make-rational
	      (exact (numerator x))
	      (exact (denominator x)))))
      (put 'sine '(scheme-number) sin)
      (put 'cosine '(scheme-number) cos)
      (put 'square-root '(scheme-number) sqrt)
      (put 'arctangent '(schemer-number) atan)
      'done)

  (define (sine x) (apply-generic 'sine x))
  (define (cosine x) (apply-generic 'cosine x))
  (define (square-root x) (apply-generic 'square-root x))
  (define (arctangent x) (apply-generic 'arctangent x))

    (define (make-scheme-number n)
      ((get 'make 'scheme-number) n))

    (define (install-rational-package)
      (define (numer x) (car x))
      (define (denom x) (cdr x))
      (define (make-rat n d)
	(let ((g (gcd n d)))
	  (cons (/ n g) (/ d g))))
      (define (add-rat x y)
	(make-rat (+ (* (numer x) (denom y))
		     (* (numer y) (denom x)))
		  (* (denom x) (denom y))))
      (define (sub-rat x y)
	(make-rat (- (* (numer x) (denom y))
		     (* (numer y) (denom x)))
		  (* (denom x) (denom y))))
      (define (mul-rat x y)
	(make-rat (* (numer x) (numer y))
		  (* (denom x) (denom y))))
      (define (div-rat x y)
	(make-rat (* (numer x) (denom y))
		  (* (denom x) (numer y))))

      (define (tag x) (attach-tag 'rational x))
      (put 'add '(rational rational)
	   (lambda (x y) (tag (add-rat x y))))
      (put 'sub '(rational rational)
	   (lambda (x y) (tag (sub-rat x y))))
      (put 'mul '(rational rational)
	   (lambda (x y) (tag (mul-rat x y))))
      (put 'div '(rational rational)
	   (lambda (x y) (tag (div-rat x y))))

      (put 'make 'rational
	   (lambda (n d) (tag (make-rat n d))))
      (put 'equ? '(rational rational)
	   (lambda (x y) (= 0 (numer (sub-rat x y)))))
      (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
      (put 'project '(rational) (lambda (x) (show #t "Calling project rational, x=" x "\n")
				   (exact (truncate (/ (numer x) (denom x))))))
      (put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
      'done)

    (define (make-rational n d)
      ((get 'make 'rational) n d))

    (define (install-rectangular-package)

      (define (real-part z) (car z))
      (define (imag-part z) (cdr z))
      (define (make-from-real-imag x y) (cons x y))
      (define (magnitude z)
	(square-root (add (square (real-part z))
			  (square (imag-part z)))))
      (define (angle z)
	(arctangent (imag-part z) (real-part z)))
      (define (make-from-mag-ang r a)
	(cons (mul r (cosine a)) (mul r (sine a))))

      (define (tag x) (attach-tag 'rectangular x))
      (put 'real-part '(rectangular) real-part)
      (put 'imag-part '(rectangular) imag-part)
      (put 'magnitude '(rectangular) magnitude)
      (put 'angle '(rectangular) angle)
      (put 'make-from-real-imag 'rectangular
	   (lambda (x y) (tag (make-from-real-imag x y))))
      (put 'make-from-mag-ang 'rectangular
	   (lambda (r a) (tag (make-from-mag-ang r a))))
      'done)

    (define (install-polar-package)

      (define (magnitude z) (car z))
      (define (angle z) (cdr z))
      (define (make-from-mag-ang r a) (cons r a))
      (define (real-part z)
	(mul (magnitude z) (cosine (angle z))))
      (define (imag-part z)
	(mul (magnitude z) (sine (angle z))))
      (define (make-from-real-imag x y)
	(cons (square-root (add (square x) (square y)))
	      (arctangent y x)))

      (define (tag x) (attach-tag 'polar x))
      (put 'real-part '(polar) real-part)
      (put 'imag-part '(polar) imag-part)
      (put 'magnitude '(polar) magnitude)
      (put 'angle '(polar) angle)
      (put 'make-from-real-imag 'polar
	   (lambda (x y) (tag (make-from-real-imag x y))))
      (put 'make-from-mag-ang 'polar
	   (lambda (r a) (tag (make-from-mag-ang r a))))
      'done)

    (define (install-complex-package)
      (define (make-from-real-imag x y)
	((get 'make-from-real-imag 'rectangular) x y))
      (define (make-from-mag-ang r a)
	((get 'make-from-mag-ang 'polar) r a))
      (define (add-complex z1 z2)
	(make-from-real-imag (add (real-part z1) (real-part z2))
			     (add (imag-part z1) (imag-part z2))))
      (define (sub-complex z1 z2)
	(make-from-real-imag (sub (real-part z1) (real-part z2))
			     (sub (imag-part z1) (imag-part z2))))
      (define (mul-complex z1 z2)
	(make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			   (add (angle z1) (angle z2))))
      (define (div-complex z1 z2)
	(make-from-mag-ang (div (magnitude z1) (magnitude z2))
			   (sub (angle z1) (angle z2))))
      (define (tag z) (attach-tag 'complex z))
      (put 'add '(complex complex)
	   (lambda (z1 z2) (tag (add-complex z1 z2))))
      (put 'sub '(complex complex)
	   (lambda (z1 z2) (tag (sub-complex z1 z2))))
      (put 'mul '(complex complex)
	   (lambda (z1 z2) (tag (mul-complex z1 z2))))
      (put 'div '(complex complex)
	   (lambda (z1 z2) (tag (div-complex z1 z2))))
      (put 'make-from-real-imag 'complex
	   (lambda (x y) (tag (make-from-real-imag x y))))
      (put 'make-from-mag-ang 'complex
	   (lambda (r a) (tag (make-from-mag-ang r a))))
      (put 'equ? '(complex complex)
	   (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
			      (= 0 (imag-part (sub-complex x y))))))
      (put 'equ? '(rectangular polar) equ?)
      (put 'equ? '(polar rectangular) equ?)
      (put 'zero? '(complex)
	   (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
      (put 'project '(complex) (lambda (z) (real-part z)))
      'done)

    (define (make-complex-from-real-imag x y)
      ((get 'make-from-real-imag 'complex) x y))

    (define (make-complex-from-mag-ang r a)
      ((get 'make-from-mag-ang 'complex) r a))

    (install-rectangular-package)
    (install-polar-package)
    (install-rational-package)
    (install-scheme-number-package)
    (install-complex-package)

    (put 'real-part '(complex) real-part)
    (put 'imag-part '(complex) imag-part)
    (put 'magnitude '(complex) magnitude)
    (put 'angle '(complex) angle)

    (define (apply-generic op . args)
      (define (all-argtypes-same? . args)
	(let ((type (type-tag (car args))))
	  (accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
      (define (coercion-if-exists? type arg-tags)
	(let ((coercion-list (map (lambda (x) 
				    (if (eq? type x)
					identity
					(get-coercion x type))) arg-tags)))
	  (if (accumulate (lambda (x y) (and x y)) #t coercion-list)
	      coercion-list
	      #f)))
      (drop (let* ((type-tags (map type-tag args))
		   (proc (get op type-tags)))
	      (cond (proc (apply proc (map contents args)))
		    ((= 1 (length args))
		     (apply-generic op (raise-type (car args))))
		    ((= 2 (length args))
		     (if (type1<=type2? (car type-tags) (cadr type-tags))
			 (apply-generic op (raise-type (car args)) (cadr args))
			 (apply-generic op (car args)  (raise-type (cadr args)))))
		    ((and (>= (length args) 2) (not (all-argtypes-same? args)))
		     (let types-loop ((types type-tags))
		       (let ((list-of-coercion-functions
			      (coercion-if-exists? (car types) type-tags)))
			 (if list-of-coercion-functions
			     (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
								list-of-coercion-functions
								args)))
			     (if (not (null? (cdr types)))
				 (types-loop (cdr types))
				 (error "apply-generic:Even coercions failed. No method for these types."))))))
		    (else (error "apply-generic:No method for these types"
				 (list op type-tags)))))))
    (define (scheme-number->complex n)
      (make-complex-from-real-imag (contents n) 0))
    (put-coercion 'scheme-number
		  'complex
		  scheme-number->complex)

    (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
						      (max (magnitude z1) (magnitude z2) (magnitude z3))))
    (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
    (define (identity x) x)

    (define numeric-tower (list 'integer 'rational 'scheme-number 'complex))

    (define (higher-type x)
      (define (find-higher-type x types)
	(cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x))
	      ((eq? x (car types)) (cadr types))
	      (else (find-higher-type x (cdr types)))))
      (find-higher-type x numeric-tower))

    (define (type1<=type2? type1 type2)
      (if (not (memq type1 numeric-tower))
	  (error "Type 1 not in the numeric tower"))
      (if (not (memq type2 numeric-tower))
	  (error "Type 2 not in the numeric tower"))
      (let loop ((types numeric-tower))
	(cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
	      ((eq? (car types) type1) #t)
	      ((eq? (car types) type2) #f)
	      (else (loop (cdr types))))))

    (define (integer->rational x)
      (make-rational x 1))

    (define (rational->scheme-number x)
      (make-scheme-number ((get 'to-real '(rational)) x)))
    (put-coercion 'integer 'rational integer->rational)
    (put-coercion 'rational 'scheme-number rational->scheme-number)

    (define (raise-type x)
      (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
	(if converter
	    (converter x)
	    (error "No coercion found for x" (type-tag x) x))))


    (define (remainder-integer a b)
      (when (or (not (integer? a)) (not (integer? b)))
	(error "Arguments must be integers" a b))
      (remainder a b))

    (put 'remainder '(integer integer) remainder-integer)
    (define (remainder-generalized a b) (apply-generic 'remainder a b))

  (define (project obj)
    (show #t "Project function: " obj "\n")
    (apply-generic 'project obj))
  (define (droppable? obj)
    (cond ((not (memq (type-tag obj) numeric-tower)) #f)
	  ((eq? (type-tag obj) (car numeric-tower)) #f)
	  ((equ? obj (raise-type (project obj))) #t)
	  (else #f)))
  (define (drop obj) 
       (if (droppable? obj)
	   (drop (project obj))
	   obj))

    (show #t "Subtracting complex numbers: "
	  (sub
	   (make-complex-from-real-imag 1.1 2)
	   (make-complex-from-real-imag 0 2)) "\n")

#+end_src

#+RESULTS:
#+begin_example
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: 1.1
Calling project 'scheme-number
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: 1.1
Calling project 'scheme-number
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (complex rectangular (rational 2476979795053773 . 2251799813685248) . 0)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: 2476979795053773/2251799813685248
Calling project 'scheme-number
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: 2476979795053773/2251799813685248
Calling project 'scheme-number
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: 2476979795053773/2251799813685248
Calling project 'scheme-number
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: 2476979795053773/2251799813685248
Calling project 'scheme-number
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: (rational 0 . 1)
Calling project rational, x=(0 . 1)
Project function: (complex rectangular (rational 2476979795053773 . 2251799813685248) . 0)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Project function: (rational 2476979795053773 . 2251799813685248)
Calling project rational, x=(2476979795053773 . 2251799813685248)
Subtracting complex numbers: (rational 2476979795053773 . 2251799813685248)
#+end_example

All right, this seems super fragile, but somehow works.


This piece will probably also be quite hairy, so it probably will be a good
idea to write down the code examples.

#+begin_src scheme :exports both :results output polynomial-package
  (define (install-polynomial-package)
    #;(internal procedures)
    #;(representation of poly)
    (define (make-poly variable term-list)
      (cons variable term-list))
    (define (variable p) (car p))
    (define (term-list p) (cdr p))

    (define (variable? x) (symbol? x))
    (define (same-variable? v1 v2)
      (and (variable? v1) (variable? v2) (eq? v1 v2)))
    (define (=number? exp num)
      (and (number? exp) (= exp num)))

    #;(representation of terms and term lists)

     (define (adjoin-term term term-list)
       (if (=zero? (coeff term))
           term-list
           (cons term term-list)))

     (define (the-empty-termlist) '())
     (define (first-term term-list) (car term-list))
     (define (rest-terms term-list) (cdr term-list))
     (define (empty-termlist? term-list) (null? term-list))

     (define (make-term order coeff) (list order coeff))
     (define (order term) (car term))
     (define (coeff term) (cadr term))

    #;(continued on next page)

     (define (add-poly p1 p2)
       (if (same-variable? (variable p1) (variable p2))
           (make-poly (variable p1)
                      (add-terms (term-list p1)
                                 (term-list p2)))
           (error "Polys not in same var -- ADD-POLY"
                  (list p1 p2))))

     (define (mul-poly p1 p2)
       (if (same-variable? (variable p1) (variable p2))
           (make-poly (variable p1)
                      (mul-terms (term-list p1)
                                 (term-list p2)))
           (error "Polys not in same var -- MUL-POLY"
                  (list p1 p2))))

    #;(interface to rest of the system)
    (define (tag p) (attach-tag 'polynomial p))
    (put 'add '(polynomial polynomial)
	 (lambda (p1 p2) (tag (add-poly p1 p2))))
    (put 'mul '(polynomial polynomial)
	 (lambda (p1 p2) (tag (mul-poly p1 p2))))
    (put 'make 'polynomial
	 (lambda (var terms) (tag (make-poly var terms))))
    'done)

     (define (add-terms L1 L2)
       (cond ((empty-termlist? L1) L2)
             ((empty-termlist? L2) L1)
             (else
              (let ((t1 (first-term L1)) (t2 (first-term L2)))
                (cond ((> (order t1) (order t2))
                       (adjoin-term
                        t1 (add-terms (rest-terms L1) L2)))
                      ((< (order t1) (order t2))
                       (adjoin-term
                        t2 (add-terms L1 (rest-terms L2))))
                      (else
                       (adjoin-term
                        (make-term (order t1)
                                   (add (coeff t1) (coeff t2)))
                        (add-terms (rest-terms L1)
                                   (rest-terms L2)))))))))
     (define (mul-terms L1 L2)
       (if (empty-termlist? L1)
           (the-empty-termlist)
           (add-terms (mul-term-by-all-terms (first-term L1) L2)
                      (mul-terms (rest-terms L1) L2))))

     (define (mul-term-by-all-terms t1 L)
       (if (empty-termlist? L)
           (the-empty-termlist)
           (let ((t2 (first-term L)))
             (adjoin-term
              (make-term (+ (order t1) (order t2))
                         (mul (coeff t1) (coeff t2)))
              (mul-term-by-all-terms t1 (rest-terms L))))))

     (define (make-polynomial var terms)
       ((get 'make 'polynomial) var terms))


#+end_src

#+RESULTS:

*** DONE Exercise 2.87 Generalized zero?
    CLOSED: [2019-10-21 Mon 18:25]

Remark 1: Even before I started solving anything, it required me 2.5 hours in
order to just make the examples run and add a couple of simple polynomials.

#+begin_src scheme :exports both :results output
	(define (accumulate op initial sequence)
	  (if (null? sequence)
	      initial
	      (accumulate op (op initial (car sequence)) (cdr sequence))))
	(define false #f)
	(define true  #t)
	(define (make-table)
	  (let ((local-table (list '*table*)))
	    (define (lookup key-1 key-2)
	      (let ((subtable (assoc key-1 (cdr local-table))))
		(if subtable
		    (let ((record (assoc key-2 (cdr subtable))))
		      (if record
			  (cdr record)
			  false))
		    false)))
	    (define (insert! key-1 key-2 value)
	      (let ((subtable (assoc key-1 (cdr local-table))))
		(if subtable
		    (let ((record (assoc key-2 (cdr subtable))))
		      (if record
			  (set-cdr! record value)
			  (set-cdr! subtable
				    (cons (cons key-2 value)
					  (cdr subtable)))))
		    (set-cdr! local-table
			      (cons (list key-1
					  (cons key-2 value))
				    (cdr local-table)))))
	      'ok)
	    (define (dispatch m)
	      (cond ((eq? m 'lookup-proc) lookup)
		    ((eq? m 'insert-proc!) insert!)
		    (else (error "Unknown operation -- TABLE" m))))
	    dispatch))

	(define operation-table (make-table))
	(define get (operation-table 'lookup-proc))
	(define put (operation-table 'insert-proc!))

	(define coercion-table (make-table))
	(define get-coercion (coercion-table 'lookup-proc))
	(define put-coercion (coercion-table 'insert-proc!))

	(define (attach-tag type-tag contents)
	  (cons type-tag contents))

	(define (type-tag datum)
	  (cond ((pair? datum) (car datum))
		((exact-integer? datum) 'integer)
		((real? datum) 'scheme-number)
		(error "Bad tagged datum -- TYPE-TAG" datum)))

	(define (contents datum)
	  (cond ((pair? datum) (cdr datum))
		((integer? datum) datum)
		((real? datum) datum)
		(else (error "Bad tagged datum -- CONTENTS" datum))))

	(define (integer? x)
	  (eq? (type-tag x) 'integer))
	(define (rectangular? z)
	  (eq? (type-tag z) 'rectangular))

	(define (polar? z)
	  (eq? (type-tag z) 'polar))


	(define (real-part z) (apply-generic 'real-part z))
	(define (imag-part z) (apply-generic 'imag-part z))
	(define (magnitude z) (apply-generic 'magnitude z))
	(define (angle z) (apply-generic 'angle z))

	(define (add x y) (apply-generic 'add x y))
	(define (sub x y) (apply-generic 'sub x y))
	(define (mul x y) (apply-generic 'mul x y))
	(define (div x y) (apply-generic 'div x y))

	(define (equ? x y)
	  (apply-generic 'equ? x y))
	(define (zero? x) (apply-generic 'zero? x))

	(define (exp x y) (apply-generic 'exp x y))

	(define (install-scheme-number-package)
	  (define (tag x)
	    (attach-tag 'scheme-number x))
	  (put 'add '(scheme-number scheme-number)
	       (lambda (x y) (tag (+ x y))))
	  (put 'sub '(scheme-number scheme-number)
	       (lambda (x y) (tag (- x y))))
	  (put 'mul '(scheme-number scheme-number)
	       (lambda (x y) (tag (* x y))))
	  (put 'div '(scheme-number scheme-number)
	       (lambda (x y) (tag (/ x y))))
	  (put 'make 'scheme-number
	       (lambda (x) (tag x)))
	  (put 'equ? '(scheme-number scheme-number)
	       (lambda (x y) (= x y)))
	  (put 'zero? '(scheme-number)
	       (lambda (x) (= 0 x)))
	  (put 'exp '(scheme-number scheme-number)
	       (lambda (x y) (tag (expt x y))))
	  (put 'project '(scheme-number)
	       (lambda (x)
		 (make-rational
		  (exact (numerator x))
		  (exact (denominator x)))))
	  (put 'sine '(scheme-number) sin)
	  (put 'cosine '(scheme-number) cos)
	  (put 'square-root '(scheme-number) sqrt)
	  (put 'arctangent '(schemer-number) atan)
	  'done)

      (define (sine x) (apply-generic 'sine x))
      (define (cosine x) (apply-generic 'cosine x))
      (define (square-root x) (apply-generic 'square-root x))
      (define (arctangent x) (apply-generic 'arctangent x))

	(define (make-scheme-number n)
	  ((get 'make 'scheme-number) n))

	(define (install-rational-package)
	  (define (numer x) (car x))
	  (define (denom x) (cdr x))
	  (define (make-rat n d)
	    (let ((g (gcd n d)))
	      (cons (/ n g) (/ d g))))
	  (define (add-rat x y)
	    (make-rat (+ (* (numer x) (denom y))
			 (* (numer y) (denom x)))
		      (* (denom x) (denom y))))
	  (define (sub-rat x y)
	    (make-rat (- (* (numer x) (denom y))
			 (* (numer y) (denom x)))
		      (* (denom x) (denom y))))
	  (define (mul-rat x y)
	    (make-rat (* (numer x) (numer y))
		      (* (denom x) (denom y))))
	  (define (div-rat x y)
	    (make-rat (* (numer x) (denom y))
		      (* (denom x) (numer y))))

	  (define (tag x) (attach-tag 'rational x))
	  (put 'add '(rational rational)
	       (lambda (x y) (tag (add-rat x y))))
	  (put 'sub '(rational rational)
	       (lambda (x y) (tag (sub-rat x y))))
	  (put 'mul '(rational rational)
	       (lambda (x y) (tag (mul-rat x y))))
	  (put 'div '(rational rational)
	       (lambda (x y) (tag (div-rat x y))))

	  (put 'make 'rational
	       (lambda (n d) (tag (make-rat n d))))
	  (put 'equ? '(rational rational)
	       (lambda (x y) (= 0 (numer (sub-rat x y)))))
	  (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
	  (put 'project '(rational) (lambda (x) 
				       (exact (truncate (/ (numer x) (denom x))))))
	  (put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
	  'done)

	(define (make-rational n d)
	  ((get 'make 'rational) n d))

	(define (install-rectangular-package)

	  (define (real-part z) (car z))
	  (define (imag-part z) (cdr z))
	  (define (make-from-real-imag x y) (cons x y))
	  (define (magnitude z)
	    (square-root (add (square (real-part z))
			      (square (imag-part z)))))
	  (define (angle z)
	    (arctangent (imag-part z) (real-part z)))
	  (define (make-from-mag-ang r a)
	    (cons (mul r (cosine a)) (mul r (sine a))))

	  (define (tag x) (attach-tag 'rectangular x))
	  (put 'real-part '(rectangular) real-part)
	  (put 'imag-part '(rectangular) imag-part)
	  (put 'magnitude '(rectangular) magnitude)
	  (put 'angle '(rectangular) angle)
	  (put 'make-from-real-imag 'rectangular
	       (lambda (x y) (tag (make-from-real-imag x y))))
	  (put 'make-from-mag-ang 'rectangular
	       (lambda (r a) (tag (make-from-mag-ang r a))))
	  'done)

	(define (install-polar-package)

	  (define (magnitude z) (car z))
	  (define (angle z) (cdr z))
	  (define (make-from-mag-ang r a) (cons r a))
	  (define (real-part z)
	    (mul (magnitude z) (cosine (angle z))))
	  (define (imag-part z)
	    (mul (magnitude z) (sine (angle z))))
	  (define (make-from-real-imag x y)
	    (cons (square-root (add (square x) (square y)))
		  (arctangent y x)))

	  (define (tag x) (attach-tag 'polar x))
	  (put 'real-part '(polar) real-part)
	  (put 'imag-part '(polar) imag-part)
	  (put 'magnitude '(polar) magnitude)
	  (put 'angle '(polar) angle)
	  (put 'make-from-real-imag 'polar
	       (lambda (x y) (tag (make-from-real-imag x y))))
	  (put 'make-from-mag-ang 'polar
	       (lambda (r a) (tag (make-from-mag-ang r a))))
	  'done)

	(define (install-complex-package)
	  (define (make-from-real-imag x y)
	    ((get 'make-from-real-imag 'rectangular) x y))
	  (define (make-from-mag-ang r a)
	    ((get 'make-from-mag-ang 'polar) r a))
	  (define (add-complex z1 z2)
	    (make-from-real-imag (add (real-part z1) (real-part z2))
				 (add (imag-part z1) (imag-part z2))))
	  (define (sub-complex z1 z2)
	    (make-from-real-imag (sub (real-part z1) (real-part z2))
				 (sub (imag-part z1) (imag-part z2))))
	  (define (mul-complex z1 z2)
	    (make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			       (add (angle z1) (angle z2))))
	  (define (div-complex z1 z2)
	    (make-from-mag-ang (div (magnitude z1) (magnitude z2))
			       (sub (angle z1) (angle z2))))
	  (define (tag z) (attach-tag 'complex z))
	  (put 'add '(complex complex)
	       (lambda (z1 z2) (tag (add-complex z1 z2))))
	  (put 'sub '(complex complex)
	       (lambda (z1 z2) (tag (sub-complex z1 z2))))
	  (put 'mul '(complex complex)
	       (lambda (z1 z2) (tag (mul-complex z1 z2))))
	  (put 'div '(complex complex)
	       (lambda (z1 z2) (tag (div-complex z1 z2))))
	  (put 'make-from-real-imag 'complex
	       (lambda (x y) (tag (make-from-real-imag x y))))
	  (put 'make-from-mag-ang 'complex
	       (lambda (r a) (tag (make-from-mag-ang r a))))
	  (put 'equ? '(complex complex)
	       (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
				  (= 0 (imag-part (sub-complex x y))))))
	  (put 'equ? '(rectangular polar) equ?)
	  (put 'equ? '(polar rectangular) equ?)
	  (put 'zero? '(complex)
	       (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
	  (put 'project '(complex) (lambda (z) (real-part z)))
	  'done)

	(define (make-complex-from-real-imag x y)
	  ((get 'make-from-real-imag 'complex) x y))

	(define (make-complex-from-mag-ang r a)
	  ((get 'make-from-mag-ang 'complex) r a))

	(install-rectangular-package)
	(install-polar-package)
	(install-rational-package)
	(install-scheme-number-package)
	(install-complex-package)

	(put 'real-part '(complex) real-part)
	(put 'imag-part '(complex) imag-part)
	(put 'magnitude '(complex) magnitude)
	(put 'angle '(complex) angle)

	(define (apply-generic op . args)
	  (define (all-argtypes-same? . args)
	    (let ((type (type-tag (car args))))
	      (accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
	  (define (coercion-if-exists? type arg-tags)
	    (let ((coercion-list (map (lambda (x) 
					(if (eq? type x)
					    identity
					    (get-coercion x type))) arg-tags)))
	      (if (accumulate (lambda (x y) (and x y)) #t coercion-list)
		  coercion-list
		  #f)))
	  (drop (let* ((type-tags (map type-tag args))
		       (proc (get op type-tags)))
		  (cond (proc (apply proc (map contents args)))
			((= 1 (length args))
			 (show #t "No proc found for op=" op ", type-tags=" type-tags "\n")
			 (apply-generic op (raise-type (car args))))
			((= 2 (length args))
			 (if (type1<=type2? (car type-tags) (cadr type-tags))
			     (apply-generic op (raise-type (car args)) (cadr args))
			     (apply-generic op (car args)  (raise-type (cadr args)))))
			((and (>= (length args) 2) (not (all-argtypes-same? args)))
			 (let types-loop ((types type-tags))
			   (let ((list-of-coercion-functions
				  (coercion-if-exists? (car types) type-tags)))
			     (if list-of-coercion-functions
				 (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
								    list-of-coercion-functions
								    args)))
				 (if (not (null? (cdr types)))
				     (types-loop (cdr types))
				     (error "apply-generic:Even coercions failed. No method for these types."))))))
			(else (error "apply-generic:No method for these types"
				     (list op type-tags)))))))
	(define (scheme-number->complex n)
	  (make-complex-from-real-imag (contents n) 0))
	(put-coercion 'scheme-number
		      'complex
		      scheme-number->complex)

	(put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
							  (max (magnitude z1) (magnitude z2) (magnitude z3))))
	(define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
	(define (identity x) x)

	(define numeric-tower (list 'integer 'rational 'scheme-number 'complex))

	(define (higher-type x)
	  (define (find-higher-type x types)
	    (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x))
		  ((eq? x (car types)) (cadr types))
		  (else (find-higher-type x (cdr types)))))
	  (find-higher-type x numeric-tower))

	(define (type1<=type2? type1 type2)
	  (if (not (memq type1 numeric-tower))
	      (error "Type 1 not in the numeric tower"))
	  (if (not (memq type2 numeric-tower))
	      (error "Type 2 not in the numeric tower"))
	  (let loop ((types numeric-tower))
	    (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
		  ((eq? (car types) type1) #t)
		  ((eq? (car types) type2) #f)
		  (else (loop (cdr types))))))

	(define (integer->rational x)
	  (make-rational x 1))

	(define (rational->scheme-number x)
	  (make-scheme-number ((get 'to-real '(rational)) x)))
	(put-coercion 'integer 'rational integer->rational)
	(put-coercion 'rational 'scheme-number rational->scheme-number)

	(define (raise-type x)
	  (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
	    (if converter
		(converter x)
		(error "No coercion found for x" (type-tag x) x))))


	(define (remainder-integer a b)
	  (when (or (not (integer? a)) (not (integer? b)))
	    (error "Arguments must be integers" a b))
	  (remainder a b))

	(put 'remainder '(integer integer) remainder-integer)
	(define (remainder-generalized a b) (apply-generic 'remainder a b))

      (define (project obj)
	(apply-generic 'project obj))
      (define (droppable? obj)
	(cond ((not (memq (type-tag obj) numeric-tower)) #f)
	      ((eq? (type-tag obj) (car numeric-tower)) #f)
	      ((equ? obj (raise-type (project obj))) #t)
	      (else #f)))
      (define (drop obj) 
	   (if (droppable? obj)
	       (drop (project obj))
	       obj))

	(show #t "Test 1: Subtracting complex numbers: "
	      (sub
	       (make-complex-from-real-imag 1.1 2)
	       (make-complex-from-real-imag 0 2)) "\n")


	(define (install-polynomial-package)
	  #;(internal procedures)
	  #;(representation of poly)
	  (define (make-poly variable term-list)
	    (cons variable term-list))
	  (define (variable p) (car p))
	  (define (term-list p)
	    (cdr p))

	  (define (variable? x) (symbol? x))
	  (define (same-variable? v1 v2)
	    (and (variable? v1) (variable? v2) (eq? v1 v2)))
	  (define (=number? exp num)
	    (and (number? exp) (= exp num)))

	  #;(representation of terms and term lists)

	   (define (adjoin-term term term-list)
	     (if (zero? (coeff term))
		 term-list
		 (cons term term-list)))

	   (define (the-empty-termlist) '())
	   (define (first-term term-list) (car term-list))
	   (define (rest-terms term-list) (cdr term-list))
	   (define (empty-termlist? term-list) (null? term-list))

	   (define (make-term order coeff) (list order coeff))
	   (define (order term) (car term))
	   (define (coeff term) (cadr term))

	  #;(continued on next page)

	   (define (add-poly p1 p2)
	     (if (same-variable? (variable p1) (variable p2))
		 (make-poly (variable p1)
			    (add-terms (term-list p1)
				       (term-list p2)))
		 (error "Polys not in same var -- ADD-POLY"
			(list p1 p2))))
	   (define (add-terms L1 L2)
	     (cond ((empty-termlist? L1) L2)
		   ((empty-termlist? L2) L1)
		   (else
		    (let ((t1 (first-term L1)) (t2 (first-term L2)))
		      (cond ((> (order t1) (order t2))
			     (adjoin-term
			      t1 (add-terms (rest-terms L1) L2)))
			    ((< (order t1) (order t2))
			     (adjoin-term
			      t2 (add-terms L1 (rest-terms L2))))
			    (else
			     (adjoin-term
			      (make-term (order t1)
					 (add (coeff t1) (coeff t2)))
			      (add-terms (rest-terms L1)
					 (rest-terms L2)))))))))

	   (define (mul-poly p1 p2)
	     (if (same-variable? (variable p1) (variable p2))
		 (make-poly (variable p1)
			    (mul-terms (term-list p1)
				       (term-list p2)))
		 (error "Polys not in same var -- MUL-POLY"
			(list p1 p2))))
	   (define (mul-terms L1 L2)
	     (if (empty-termlist? L1)
		 (the-empty-termlist)
		 (add-terms (mul-term-by-all-terms (first-term L1) L2)
			    (mul-terms (rest-terms L1) L2))))

	   (define (mul-term-by-all-terms t1 L)
	     (if (empty-termlist? L)
		 (the-empty-termlist)
		 (let ((t2 (first-term L)))
		   (adjoin-term
		    (make-term (+ (order t1) (order t2))
			       (mul (coeff t1) (coeff t2)))
		    (mul-term-by-all-terms t1 (rest-terms L))))))
	  (define (zero-poly? poly)
	    (show #t "zero-poly?: poly=" poly "\n")
	    (cond ((empty-termlist? (term-list poly)) #t)
		  ((every (lambda (x) (apply-generic 'zero? (coeff x))) (term-list poly)) #t)
		  (else #f)))
	  #;(interface to rest of the system)
	  (define (tag p) (attach-tag 'polynomial p))
	  (put 'add '(polynomial polynomial)
	       (lambda (p1 p2) (tag (add-poly p1 p2))))
	  (put 'mul '(polynomial polynomial)
	       (lambda (p1 p2) (tag (mul-poly p1 p2))))
	  (put 'make 'polynomial
	       (lambda (var terms) (tag (make-poly var terms))))
	  (put 'zero? '(polynomial) zero-poly?)
	  'done)
    (install-polynomial-package)

	   (define (make-polynomial var terms)
	     ((get 'make 'polynomial) var terms))
      (show #t "Test 2: Making polynomials: " 
	    (make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
      (show #t "Test 3: Adding polynomials: "
	    (add (make-polynomial 'x '((5 1) (4 2) (0 1)))
		 (make-polynomial 'x '((5 1)))) "\n")
      (show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")
#+end_src

#+RESULTS:
: Test 1: Subtracting complex numbers: (rational 2476979795053773 . 2251799813685248)
: Test 2: Making polynomials: (polynomial x (5 1) (4 2))
: No proc found for op=zero?, type-tags=(integer)
: Test 3: Adding polynomials: (polynomial x (5 2) (4 2) (0 1))
: zero-poly?: poly=(x (5 0) (3 1))
: No proc found for op=zero?, type-tags=(integer)
: No proc found for op=zero?, type-tags=(integer)
: Test 4: Zero?: #f

Even though making the example code turned out to be a huge pain, actually
solving the puzzle wasn't that hard. Just added a predicate to check if every
coefficient of a polynomial is zero.

*** DONE Exercise 2.88 Subtraction of polynomials
    CLOSED: [2019-10-22 Tue 09:55]

I am copying the code again. We would need to implement a generalized
subtraction function.

This task turned out to be super-easy.

#+begin_src scheme :exports both :results output
  (define (accumulate op initial sequence)
    (if (null? sequence)
	initial
	(accumulate op (op initial (car sequence)) (cdr sequence))))
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (cond ((pair? datum) (car datum))
	  ((exact-integer? datum) 'integer)
	  ((real? datum) 'scheme-number)
	  (error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (cond ((pair? datum) (cdr datum))
	  ((integer? datum) datum)
	  ((real? datum) datum)
	  (else (error "Bad tagged datum -- CONTENTS" datum))))

  (define (integer? x)
    (eq? (type-tag x) 'integer))
  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y)
    (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	 (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	 (lambda (x y) (tag (expt x y))))
    (put 'project '(scheme-number)
	 (lambda (x)
	   (make-rational
	    (exact (numerator x))
	    (exact (denominator x)))))
    (put 'sine '(scheme-number) sin)
    (put 'cosine '(scheme-number) cos)
    (put 'square-root '(scheme-number) sqrt)
    (put 'arctangent '(schemer-number) atan)
    'done)

  (define (sine x) (apply-generic 'sine x))
  (define (cosine x) (apply-generic 'cosine x))
  (define (square-root x) (apply-generic 'square-root x))
  (define (arctangent x) (apply-generic 'arctangent x))

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    (put 'project '(rational) (lambda (x) 
				(exact (truncate (/ (numer x) (denom x))))))
    (put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (square-root (add (square (real-part z))
			(square (imag-part z)))))
    (define (angle z)
      (arctangent (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (mul r (cosine a)) (mul r (sine a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (mul (magnitude z) (cosine (angle z))))
    (define (imag-part z)
      (mul (magnitude z) (sine (angle z))))
    (define (make-from-real-imag x y)
      (cons (square-root (add (square x) (square y)))
	    (arctangent y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (add (real-part z1) (real-part z2))
			   (add (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (sub (real-part z1) (real-part z2))
			   (sub (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			 (add (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (div (magnitude z1) (magnitude z2))
			 (sub (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
			    (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    (put 'project '(complex) (lambda (z) (real-part z)))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))

  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

  (put 'real-part '(complex) real-part)
  (put 'imag-part '(complex) imag-part)
  (put 'magnitude '(complex) magnitude)
  (put 'angle '(complex) angle)

  (define (apply-generic op . args)
    (define (all-argtypes-same? . args)
      (let ((type (type-tag (car args))))
	(accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
    (define (coercion-if-exists? type arg-tags)
      (let ((coercion-list (map (lambda (x) 
				  (if (eq? type x)
				      identity
				      (get-coercion x type))) arg-tags)))
	(if (accumulate (lambda (x y) (and x y)) #t coercion-list)
	    coercion-list
	    #f)))
    (drop (let* ((type-tags (map type-tag args))
		 (proc (get op type-tags)))
	    (cond (proc (apply proc (map contents args)))
		  ((= 1 (length args))
		   #;(show #t "No proc found for op=" op ", type-tags=" type-tags "\n")
		   (apply-generic op (raise-type (car args))))
		  ((= 2 (length args))
		   (if (type1<=type2? (car type-tags) (cadr type-tags))
		       (apply-generic op (raise-type (car args)) (cadr args))
		       (apply-generic op (car args)  (raise-type (cadr args)))))
		  ((and (>= (length args) 2) (not (all-argtypes-same? args)))
		   (let types-loop ((types type-tags))
		     (let ((list-of-coercion-functions
			    (coercion-if-exists? (car types) type-tags)))
		       (if list-of-coercion-functions
			   (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
							      list-of-coercion-functions
							      args)))
			   (if (not (null? (cdr types)))
			       (types-loop (cdr types))
			       (error "apply-generic:Even coercions failed. No method for these types."))))))
		  (else (error "apply-generic:No method for these types"
			       (list op type-tags)))))))
  (define (scheme-number->complex n)
    (make-complex-from-real-imag (contents n) 0))
  (put-coercion 'scheme-number
		'complex
		scheme-number->complex)

  (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
						    (max (magnitude z1) (magnitude z2) (magnitude z3))))
  (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
  (define (identity x) x)

  (define numeric-tower (list 'integer 'rational 'scheme-number 'complex))

  (define (higher-type x)
    (define (find-higher-type x types)
      (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x))
	    ((eq? x (car types)) (cadr types))
	    (else (find-higher-type x (cdr types)))))
    (find-higher-type x numeric-tower))

  (define (type1<=type2? type1 type2)
    (if (not (memq type1 numeric-tower))
	(error "Type 1 not in the numeric tower"))
    (if (not (memq type2 numeric-tower))
	(error "Type 2 not in the numeric tower"))
    (let loop ((types numeric-tower))
      (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
	    ((eq? (car types) type1) #t)
	    ((eq? (car types) type2) #f)
	    (else (loop (cdr types))))))

  (define (integer->rational x)
    (make-rational x 1))

  (define (rational->scheme-number x)
    (make-scheme-number ((get 'to-real '(rational)) x)))
  (put-coercion 'integer 'rational integer->rational)
  (put-coercion 'rational 'scheme-number rational->scheme-number)

  (define (raise-type x)
    (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
      (if converter
	  (converter x)
	  (error "No coercion found for x" (type-tag x) x))))


  (define (remainder-integer a b)
    (when (or (not (integer? a)) (not (integer? b)))
      (error "Arguments must be integers" a b))
    (remainder a b))

  (put 'remainder '(integer integer) remainder-integer)
  (define (remainder-generalized a b) (apply-generic 'remainder a b))

  (define (project obj)
    (apply-generic 'project obj))
  (define (droppable? obj)
    (cond ((not (memq (type-tag obj) numeric-tower)) #f)
	  ((eq? (type-tag obj) (car numeric-tower)) #f)
	  ((equ? obj (raise-type (project obj))) #t)
	  (else #f)))
  (define (drop obj) 
    (if (droppable? obj)
	(drop (project obj))
	obj))

  (show #t "Test 1: Subtracting complex numbers: "
	(sub
	 (make-complex-from-real-imag 1.1 2)
	 (make-complex-from-real-imag 0 2)) "\n")


  (define (install-polynomial-package)
    #;(internal procedures)
    #;(representation of poly)
    (define (make-poly variable term-list)
      (cons variable term-list))
    (define (variable p) (car p))
    (define (term-list p)
      (cdr p))

    (define (variable? x) (symbol? x))
    (define (same-variable? v1 v2)
      (and (variable? v1) (variable? v2) (eq? v1 v2)))
    (define (=number? exp num)
      (and (number? exp) (= exp num)))

    #;(representation of terms and term lists)

    (define (adjoin-term term term-list)
      (if (zero? (coeff term))
	  term-list
	  (cons term term-list)))

    (define (the-empty-termlist) '())
    (define (first-term term-list) (car term-list))
    (define (rest-terms term-list) (cdr term-list))
    (define (empty-termlist? term-list) (null? term-list))

    (define (make-term order coeff) (list order coeff))
    (define (order term) (car term))
    (define (coeff term) (cadr term))

    #;(continued on next page)

    (define (add-poly p1 p2)
      (if (same-variable? (variable p1) (variable p2))
	  (make-poly (variable p1)
		     (add-terms (term-list p1)
				(term-list p2)))
	  (error "Polys not in same var -- ADD-POLY"
		 (list p1 p2))))
    (define (sub-poly p1 p2)
      (add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
    (define (add-terms L1 L2)
      (cond ((empty-termlist? L1) L2)
	    ((empty-termlist? L2) L1)
	    (else
	     (let ((t1 (first-term L1)) (t2 (first-term L2)))
	       (cond ((> (order t1) (order t2))
		      (adjoin-term
		       t1 (add-terms (rest-terms L1) L2)))
		     ((< (order t1) (order t2))
		      (adjoin-term
		       t2 (add-terms L1 (rest-terms L2))))
		     (else
		      (adjoin-term
		       (make-term (order t1)
				  (add (coeff t1) (coeff t2)))
		       (add-terms (rest-terms L1)
				  (rest-terms L2)))))))))


    (define (mul-poly p1 p2)
      (if (same-variable? (variable p1) (variable p2))
	  (make-poly (variable p1)
		     (mul-terms (term-list p1)
				(term-list p2)))
	  (error "Polys not in same var -- MUL-POLY"
		 (list p1 p2))))
    (define (mul-terms L1 L2)
      (if (empty-termlist? L1)
	  (the-empty-termlist)
	  (add-terms (mul-term-by-all-terms (first-term L1) L2)
		     (mul-terms (rest-terms L1) L2))))

    (define (mul-term-by-all-terms t1 L)
      (if (empty-termlist? L)
	  (the-empty-termlist)
	  (let ((t2 (first-term L)))
	    (adjoin-term
	     (make-term (+ (order t1) (order t2))
			(mul (coeff t1) (coeff t2)))
	     (mul-term-by-all-terms t1 (rest-terms L))))))
    (define (zero-poly? poly)
      (show #t "zero-poly?: poly=" poly "\n")
      (cond ((empty-termlist? (term-list poly)) #t)
	    ((every (lambda (x) (apply-generic 'zero? (coeff x))) (term-list poly)) #t)
	    (else #f)))
    #;(interface to rest of the system)
    (define (tag p) (attach-tag 'polynomial p))
    (put 'add '(polynomial polynomial)
	 (lambda (p1 p2) (tag (add-poly p1 p2))))
    (put 'mul '(polynomial polynomial)
	 (lambda (p1 p2) (tag (mul-poly p1 p2))))
    (put 'sub '(polynomial polynomial)
	 (lambda (p1 p2) (tag (sub-poly p1 p2))))
    (put 'make 'polynomial
	 (lambda (var terms) (tag (make-poly var terms))))
    (put 'zero? '(polynomial) zero-poly?)
    'done)
  (install-polynomial-package)

  (define (make-polynomial var terms)
    ((get 'make 'polynomial) var terms))
  (show #t "Test 2: Making polynomials: " 
	(make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
  (show #t "Test 3: Adding polynomials: "
	(add (make-polynomial 'x '((5 1) (4 2) (0 1)))
	     (make-polynomial 'x '((5 1)))) "\n")
  (show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

  (show #t "Test 5: Subtracting polynomials: "
	(sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
	     (make-polynomial 'x '((0 1)))) "\n")
#+end_src

#+RESULTS:
: Test 1: Subtracting complex numbers: (rational 2476979795053773 . 2251799813685248)
: Test 2: Making polynomials: (polynomial x (5 1) (4 2))
: Test 3: Adding polynomials: (polynomial x (5 2) (4 2) (0 1))
: zero-poly?: poly=(x (5 0) (3 1))
: Test 4: Zero?: #f
: Test 5: Subtracting polynomials: (polynomial x (5 1) (4 2))

*** DONE Exercise 2.89 Dense term-lists
    CLOSED: [2019-10-22 Tue 11:55]

This is a contrived exercise, frankly. It's purpose, I guess, is to just
prepare the reader for the next exercise, which would be too big
otherwise. The functions we are going to write here will serve as a basis for
the Exercise 2.90, where we will pack them into a separate package.

This exercise is also easy, the main trick is to understand that a term and a
term-list are two separate things and that the latter is not necessarily the
set of the former. 

The sparse list-based ~adjoin-term~ seems to be only adjoining higher terms, not
lower, so my dense list-based only supports that too. In any case, adding the
option to adjoin smaller terms seems to be possible if needed.

#+begin_src scheme :exports both :results output
    (define (adjoin-term term term-list)
      (if (zero? (coeff term))
	  term-list
	  (if (> (order term) (length term-list))
	      (append (list (coeff term))
		      (make-list (- (order term) (length term-list)) 0)
		      term-list)
	      (error "adjoin-term:Appending a smaller order term. Recheck."))))

    (define (the-empty-termlist) '())
    (define (first-term term-list) (make-term (car term-list)) (length (cdr term-list)))
    (define (rest-terms term-list) (cdr term-list))
    (define (empty-termlist? term-list) (null? term-list))

    (define (make-term order coeff) (list order coeff))
    (define (order term) (car term))
    (define (coeff term) (cadr term))


(show #t "Test 1: appending zero: " (adjoin-term (make-term 100 0) (the-empty-termlist)) "\n")
(show #t "Test 2: appending zero: " (adjoin-term (make-term 100 0) '(1)) "\n")
(show #t "Test 2: appending zero: " (adjoin-term (make-term 10 1) '(1)) "\n")

#+end_src

#+RESULTS:
: Test 1: appending zero: ()
: Test 2: appending zero: (1)
: Test 2: appending zero: (1 0 0 0 0 0 0 0 0 0 1)

*** DONE Exercise 2.90 Implementing dense polynomials as a separate package
    CLOSED: [2019-10-22 Tue 21:31]

Again, since implementing the new package will require a major rewrite of the
system, it's better to copy the code rather than tangle.

#+begin_src scheme :exports both :results output
  (define (accumulate op initial sequence)
    (if (null? sequence)
	initial
	(accumulate op (op initial (car sequence)) (cdr sequence))))
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (cond ((pair? datum) (car datum))
	  ((exact-integer? datum) 'integer)
	  ((real? datum) 'scheme-number)
	  (error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (cond ((pair? datum) (cdr datum))
	  ((integer? datum) datum)
	  ((real? datum) datum)
	  (else (error "Bad tagged datum -- CONTENTS" datum))))

  (define (integer? x)
    (eq? (type-tag x) 'integer))
  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y)
    (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	 (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	 (lambda (x y) (tag (expt x y))))
    (put 'project '(scheme-number)
	 (lambda (x)
	   (make-rational
	    (exact (numerator x))
	    (exact (denominator x)))))
    (put 'sine '(scheme-number) sin)
    (put 'cosine '(scheme-number) cos)
    (put 'square-root '(scheme-number) sqrt)
    (put 'arctangent '(schemer-number) atan)
    'done)

  (define (sine x) (apply-generic 'sine x))
  (define (cosine x) (apply-generic 'cosine x))
  (define (square-root x) (apply-generic 'square-root x))
  (define (arctangent x) (apply-generic 'arctangent x))

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    (put 'project '(rational) (lambda (x) 
				(exact (truncate (/ (numer x) (denom x))))))
    (put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (square-root (add (square (real-part z))
			(square (imag-part z)))))
    (define (angle z)
      (arctangent (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (mul r (cosine a)) (mul r (sine a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (mul (magnitude z) (cosine (angle z))))
    (define (imag-part z)
      (mul (magnitude z) (sine (angle z))))
    (define (make-from-real-imag x y)
      (cons (square-root (add (square x) (square y)))
	    (arctangent y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (add (real-part z1) (real-part z2))
			   (add (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (sub (real-part z1) (real-part z2))
			   (sub (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			 (add (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (div (magnitude z1) (magnitude z2))
			 (sub (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
			    (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    (put 'project '(complex) (lambda (z) (real-part z)))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))

  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

  (put 'real-part '(complex) real-part)
  (put 'imag-part '(complex) imag-part)
  (put 'magnitude '(complex) magnitude)
  (put 'angle '(complex) angle)

  (define (apply-generic op . args)
    (define (all-argtypes-same? . args)
      (let ((type (type-tag (car args))))
	(accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
    (define (coercion-if-exists? type arg-tags)
      (let ((coercion-list (map (lambda (x) 
				  (if (eq? type x)
				      identity
				      (get-coercion x type))) arg-tags)))
	(if (accumulate (lambda (x y) (and x y)) #t coercion-list)
	    coercion-list
	    #f)))
    (drop (let* ((type-tags (map type-tag args))
		 (proc (get op type-tags)))
	    (cond (proc (apply proc (map contents args)))
		  ((= 1 (length args))
		   #;(show #t "No proc found for op=" op ", type-tags=" type-tags "\n")
		   (apply-generic op (raise-type (car args))))
		  ((= 2 (length args))
		   (if (type1<=type2? (car type-tags) (cadr type-tags))
		       (apply-generic op (raise-type (car args)) (cadr args))
		       (apply-generic op (car args)  (raise-type (cadr args)))))
		  ((and (>= (length args) 2) (not (all-argtypes-same? args)))
		   (let types-loop ((types type-tags))
		     (let ((list-of-coercion-functions
			    (coercion-if-exists? (car types) type-tags)))
		       (if list-of-coercion-functions
			   (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
							      list-of-coercion-functions
							      args)))
			   (if (not (null? (cdr types)))
			       (types-loop (cdr types))
			       (error "apply-generic:Even coercions failed. No method for these types."))))))
		  (else (error "apply-generic:No method for these types"
			       (list op type-tags)))))))
  (define (scheme-number->complex n)
    (make-complex-from-real-imag (contents n) 0))
  (put-coercion 'scheme-number
		'complex
		scheme-number->complex)

  (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
						    (max (magnitude z1) (magnitude z2) (magnitude z3))))
  (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
  (define (identity x) x)

  (define numeric-tower (list 'integer 'rational 'scheme-number 'complex))

  (define (higher-type x)
    (define (find-higher-type x types)
      (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x))
	    ((eq? x (car types)) (cadr types))
	    (else (find-higher-type x (cdr types)))))
    (find-higher-type x numeric-tower))

  (define (type1<=type2? type1 type2)
    (if (not (memq type1 numeric-tower))
	(error "Type 1 not in the numeric tower"))
    (if (not (memq type2 numeric-tower))
	(error "Type 2 not in the numeric tower"))
    (let loop ((types numeric-tower))
      (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
	    ((eq? (car types) type1) #t)
	    ((eq? (car types) type2) #f)
	    (else (loop (cdr types))))))

  (define (integer->rational x)
    (make-rational x 1))

  (define (rational->scheme-number x)
    (make-scheme-number ((get 'to-real '(rational)) x)))
  (put-coercion 'integer 'rational integer->rational)
  (put-coercion 'rational 'scheme-number rational->scheme-number)

  (define (raise-type x)
    (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
      (if converter
	  (converter x)
	  (error "No coercion found for x" (type-tag x) x))))


  (define (remainder-integer a b)
    (when (or (not (integer? a)) (not (integer? b)))
      (error "Arguments must be integers" a b))
    (remainder a b))

  (put 'remainder '(integer integer) remainder-integer)
  (define (remainder-generalized a b) (apply-generic 'remainder a b))

  (define (project obj)
    (apply-generic 'project obj))
  (define (droppable? obj)
    (cond ((not (memq (type-tag obj) numeric-tower)) #f)
	  ((eq? (type-tag obj) (car numeric-tower)) #f)
	  ((equ? obj (raise-type (project obj))) #t)
	  (else #f)))
  (define (drop obj) 
    (if (droppable? obj)
	(drop (project obj))
	obj))

  (show #t "Test 1: Subtracting complex numbers: "
	(sub
	 (make-complex-from-real-imag 1.1 2)
	 (make-complex-from-real-imag 0 2)) "\n")
  (define (install-polynomial-package)
    (define (make-poly variable term-list)
      (cons variable term-list))
    (define (variable p) (car p))
    (define (term-list p)
      (cdr p))
    (define (variable? x) (symbol? x))
    (define (same-variable? v1 v2)
      (and (variable? v1) (variable? v2) (eq? v1 v2)))
    (define (=number? exp num)
      (and (number? exp) (= exp num)))
    (define (the-empty-termlist) '())

    (define (rest-terms term-list) (cdr term-list))
    (define (empty-termlist? term-list) (null? term-list))

    (define (make-term order coeff) (list order coeff))
    (define (order term) (car term))
    (define (coeff term) (cadr term))

    #;(continued on next page)

    (define (add-poly p1 p2)
      (if (same-variable? (variable p1) (variable p2))
	  (make-poly (variable p1)
		     (add-terms (term-list p1)
				(term-list p2)))
	  (error "Polys not in same var -- ADD-POLY"
		 (list p1 p2))))
    (define (sub-poly p1 p2)
      (add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
    (define (add-terms L1 L2)
      (cond ((empty-termlist? L1) L2)
	    ((empty-termlist? L2) L1)
	    (else
	     (let ((t1 (first-term L1)) (t2 (first-term L2)))
	       (cond ((> (order t1) (order t2))
		      (adjoin-term
		       t1 (add-terms (rest-terms L1) L2)))
		     ((< (order t1) (order t2))
		      (adjoin-term
		       t2 (add-terms L1 (rest-terms L2))))
		     (else
		      (adjoin-term
		       (make-term (order t1)
				  (add (coeff t1) (coeff t2)))
		       (add-terms (rest-terms L1)
				  (rest-terms L2)))))))))


    (define (mul-poly p1 p2)
      (if (same-variable? (variable p1) (variable p2))
	  (make-poly (variable p1)
		     (mul-terms (term-list p1)
				(term-list p2)))
	  (error "Polys not in same var -- MUL-POLY"
		 (list p1 p2))))
    (define (mul-terms L1 L2)
      (if (empty-termlist? L1)
	  (the-empty-termlist)
	  (add-terms (mul-term-by-all-terms (first-term L1) L2)
		     (mul-terms (rest-terms L1) L2))))

    (define (mul-term-by-all-terms t1 L)
      (if (empty-termlist? L)
	  (the-empty-termlist)
	  (let ((t2 (first-term L)))
	    (adjoin-term
	     (make-term (+ (order t1) (order t2))
			(mul (coeff t1) (coeff t2)))
	     (mul-term-by-all-terms t1 (rest-terms L))))))
    (define (zero-poly? poly)
      #;(show #t "zero-poly?: poly=" (displayed poly) "\n")
      (cond ((empty-termlist? (term-list poly)) #t)
	    ((not (= 0 (coeff (first-term (term-list poly))))) #f)
	    (else (zero-poly? 
		   (make-poly (variable poly)
			      (rest-terms (term-list poly)))))))
    (define (tag p) (attach-tag 'polynomial p))
    (define (termlist-type-of term-list)
      #;(show #t "t-t-o: term-list=" (displayed term-list) "\n")
      (cond ((null? term-list) 'sparse)
	    ((pair? (car term-list)) 'sparse)
	    ((list? term-list) 'dense)
	    (else (error "Unknown type of list" term-list))))
    (define (adjoin-term term term-list)
      ((get 'adjoin-term (termlist-type-of term-list)) term term-list))
    (define (first-term term-list)
      #;(show #t "first-term: term-list=" (displayed term-list) "\n")
      #;(show #t "first-term: term-list-type=" (displayed (termlist-type-of term-list)) "\n")
      ((get 'first-term (termlist-type-of term-list)) term-list))
    (put 'add '(polynomial polynomial)
	 (lambda (p1 p2) (tag (add-poly p1 p2))))
    (put 'mul '(polynomial polynomial)
	 (lambda (p1 p2) (tag (mul-poly p1 p2))))
    (put 'sub '(polynomial polynomial)
	 (lambda (p1 p2) (tag (sub-poly p1 p2))))
    (put 'make 'polynomial
	 (lambda (var terms) (tag (make-poly var terms))))
    (put 'zero? '(polynomial) zero-poly?)
    'done)
  (install-polynomial-package)

  (define (install-polynomial-sparse-package)
    (define (coeff term) (cadr term))
    (define (first-term-sparse term-list) (car term-list))
    (define (adjoin-term-sparse term term-list)
      (if (zero? (coeff term))
	  term-list
	  (cons term term-list)))
    (put 'adjoin-term 'sparse adjoin-term-sparse)
    (put 'first-term 'sparse first-term-sparse)
    'done)
  (install-polynomial-sparse-package)

  (define (install-polynomial-dense-package)
    (define (make-term order coeff) (list order coeff))
    (define (order term) (car term))
    (define (coeff term) (cadr term))

    (define (adjoin-term-dense term term-list)
	(if (zero? (coeff term))
	    term-list
	    (if (> (order term) (length term-list))
		(append (list (coeff term))
			(make-list (- (order term) (length term-list)) 0)
			term-list)
		(error "adjoin-term:Appending a smaller order term. Recheck."))))
    (define (first-term-dense term-list) 
       #;(show #t "first-term-dense: " (displayed (make-term (car term-list) (length (cdr term-list)))) "\n")
       (make-term (length (cdr term-list)) (car term-list) ))
    (put 'adjoin-term 'dense adjoin-term-dense)
    (put 'first-term 'dense first-term-dense)
    'done)
  (install-polynomial-dense-package)

  (define (make-polynomial var terms)
    ((get 'make 'polynomial) var terms))
  (show #t "Test 2: Making polynomials: " 
	(make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
  (show #t "Test 3: Zero?: " 
	(zero? (make-polynomial 'x (list (list 5 1) (list 4 2)))) "\n")
  (show #t "Test 4: Adding polynomials: "
	(add (make-polynomial 'x '((5 1) (4 2) (0 1)))
	     (make-polynomial 'x '((5 1)))) "\n")
  #;(show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

  (show #t "Test 5: Subtracting polynomials: "
	(sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
	     (make-polynomial 'x '((0 1)))) "\n")

  (show #t "Test 6: Making a dense polynomial: " (make-polynomial 'x '(1 2 3 4 5)) "\n")
  (show #t "Test 7: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(0)))) "\n")
  (show #t "Test 8: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(1)))) "\n")
  (show #t "Test 9: Adding dense polynomials: "
	(add (make-polynomial 'x '(1 2 0 0 0 1))
	     (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
  (show #t "Test10: Subtracting dense polynomials: "
	(sub (make-polynomial 'x '(1 2 0 0 0 1))
	     (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
  (show #t "Test11: Subtracting dense and sparse polynomials: "
	(sub (make-polynomial 'x '(1 2 0 0 0 1))
	     (make-polynomial 'x '((4 2)))) "\n")
#+end_src

#+RESULTS:
#+begin_example
Test 1: Subtracting complex numbers: (rational 2476979795053773 . 2251799813685248)
Test 2: Making polynomials: (polynomial x (5 1) (4 2))
Test 3: Zero?: #f
Test 4: Adding polynomials: (polynomial x (5 2) (4 2) (0 1))
Test 5: Subtracting polynomials: (polynomial x (5 1) (4 2))
Test 6: Making a dense polynomial: (polynomial x 1 2 3 4 5)
Test 7: zero? dense polynomial: #t
Test 8: zero? dense polynomial: #f
Test 9: Adding dense polynomials: (polynomial x (5 2) (4 2) (0 1))
Test10: Subtracting dense polynomials: (polynomial x 2 0 0 0 1)
Test11: Subtracting dense and sparse polynomials: (polynomial x 1 0 0 0 0 1)
#+end_example

This also turned out to be not such a difficult exercise. The slightly
controversial thing that I am concerned with is that the function
~termlist-type-of~ is not based on tags, and is not even using the main
generic dispatch subsystem. But so far this seems good enough.

*** DONE Exercise 2.91 Division of polynomials
    CLOSED: [2019-10-23 Wed 00:11]
And again, since div-poly is an internal procedure of the polynomial package,
let me copy the whole code.

#+begin_src scheme :exports both :results output
  (define (accumulate op initial sequence)
    (if (null? sequence)
	initial
	(accumulate op (op initial (car sequence)) (cdr sequence))))
  (define false #f)
  (define true  #t)
  (define (make-table)
    (let ((local-table (list '*table*)))
      (define (lookup key-1 key-2)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (cdr record)
		    false))
	      false)))
      (define (insert! key-1 key-2 value)
	(let ((subtable (assoc key-1 (cdr local-table))))
	  (if subtable
	      (let ((record (assoc key-2 (cdr subtable))))
		(if record
		    (set-cdr! record value)
		    (set-cdr! subtable
			      (cons (cons key-2 value)
				    (cdr subtable)))))
	      (set-cdr! local-table
			(cons (list key-1
				    (cons key-2 value))
			      (cdr local-table)))))
	'ok)
      (define (dispatch m)
	(cond ((eq? m 'lookup-proc) lookup)
	      ((eq? m 'insert-proc!) insert!)
	      (else (error "Unknown operation -- TABLE" m))))
      dispatch))

  (define operation-table (make-table))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))

  (define coercion-table (make-table))
  (define get-coercion (coercion-table 'lookup-proc))
  (define put-coercion (coercion-table 'insert-proc!))

  (define (attach-tag type-tag contents)
    (cons type-tag contents))

  (define (type-tag datum)
    (cond ((pair? datum) (car datum))
	  ((exact-integer? datum) 'integer)
	  ((real? datum) 'scheme-number)
	  (error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
    (cond ((pair? datum) (cdr datum))
	  ((integer? datum) datum)
	  ((real? datum) datum)
	  (else (error "Bad tagged datum -- CONTENTS" datum))))

  (define (integer? x)
    (eq? (type-tag x) 'integer))
  (define (rectangular? z)
    (eq? (type-tag z) 'rectangular))

  (define (polar? z)
    (eq? (type-tag z) 'polar))


  (define (real-part z) (apply-generic 'real-part z))
  (define (imag-part z) (apply-generic 'imag-part z))
  (define (magnitude z) (apply-generic 'magnitude z))
  (define (angle z) (apply-generic 'angle z))

  (define (add x y) (apply-generic 'add x y))
  (define (sub x y) (apply-generic 'sub x y))
  (define (mul x y) (apply-generic 'mul x y))
  (define (div x y) (apply-generic 'div x y))

  (define (equ? x y)
    (apply-generic 'equ? x y))
  (define (zero? x) (apply-generic 'zero? x))

  (define (exp x y) (apply-generic 'exp x y))

  (define (install-scheme-number-package)
    (define (tag x)
      (attach-tag 'scheme-number x))
    (put 'add '(scheme-number scheme-number)
	 (lambda (x y) (tag (+ x y))))
    (put 'sub '(scheme-number scheme-number)
	 (lambda (x y) (tag (- x y))))
    (put 'mul '(scheme-number scheme-number)
	 (lambda (x y) (tag (* x y))))
    (put 'div '(scheme-number scheme-number)
	 (lambda (x y) (tag (/ x y))))
    (put 'make 'scheme-number
	 (lambda (x) (tag x)))
    (put 'equ? '(scheme-number scheme-number)
	 (lambda (x y) (= x y)))
    (put 'zero? '(scheme-number)
	 (lambda (x) (= 0 x)))
    (put 'exp '(scheme-number scheme-number)
	 (lambda (x y) (tag (expt x y))))
    (put 'project '(scheme-number)
	 (lambda (x)
	   (make-rational
	    (exact (numerator x))
	    (exact (denominator x)))))
    (put 'sine '(scheme-number) sin)
    (put 'cosine '(scheme-number) cos)
    (put 'square-root '(scheme-number) sqrt)
    (put 'arctangent '(schemer-number) atan)
    'done)

  (define (sine x) (apply-generic 'sine x))
  (define (cosine x) (apply-generic 'cosine x))
  (define (square-root x) (apply-generic 'square-root x))
  (define (arctangent x) (apply-generic 'arctangent x))

  (define (make-scheme-number n)
    ((get 'make 'scheme-number) n))

  (define (install-rational-package)
    (define (numer x) (car x))
    (define (denom x) (cdr x))
    (define (make-rat n d)
      (let ((g (gcd n d)))
	(cons (/ n g) (/ d g))))
    (define (add-rat x y)
      (make-rat (+ (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (sub-rat x y)
      (make-rat (- (* (numer x) (denom y))
		   (* (numer y) (denom x)))
		(* (denom x) (denom y))))
    (define (mul-rat x y)
      (make-rat (* (numer x) (numer y))
		(* (denom x) (denom y))))
    (define (div-rat x y)
      (make-rat (* (numer x) (denom y))
		(* (denom x) (numer y))))

    (define (tag x) (attach-tag 'rational x))
    (put 'add '(rational rational)
	 (lambda (x y) (tag (add-rat x y))))
    (put 'sub '(rational rational)
	 (lambda (x y) (tag (sub-rat x y))))
    (put 'mul '(rational rational)
	 (lambda (x y) (tag (mul-rat x y))))
    (put 'div '(rational rational)
	 (lambda (x y) (tag (div-rat x y))))

    (put 'make 'rational
	 (lambda (n d) (tag (make-rat n d))))
    (put 'equ? '(rational rational)
	 (lambda (x y) (= 0 (numer (sub-rat x y)))))
    (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
    (put 'project '(rational) (lambda (x) 
				(exact (truncate (/ (numer x) (denom x))))))
    (put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
    'done)

  (define (make-rational n d)
    ((get 'make 'rational) n d))

  (define (install-rectangular-package)

    (define (real-part z) (car z))
    (define (imag-part z) (cdr z))
    (define (make-from-real-imag x y) (cons x y))
    (define (magnitude z)
      (square-root (add (square (real-part z))
			(square (imag-part z)))))
    (define (angle z)
      (arctangent (imag-part z) (real-part z)))
    (define (make-from-mag-ang r a)
      (cons (mul r (cosine a)) (mul r (sine a))))

    (define (tag x) (attach-tag 'rectangular x))
    (put 'real-part '(rectangular) real-part)
    (put 'imag-part '(rectangular) imag-part)
    (put 'magnitude '(rectangular) magnitude)
    (put 'angle '(rectangular) angle)
    (put 'make-from-real-imag 'rectangular
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'rectangular
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-polar-package)

    (define (magnitude z) (car z))
    (define (angle z) (cdr z))
    (define (make-from-mag-ang r a) (cons r a))
    (define (real-part z)
      (mul (magnitude z) (cosine (angle z))))
    (define (imag-part z)
      (mul (magnitude z) (sine (angle z))))
    (define (make-from-real-imag x y)
      (cons (square-root (add (square x) (square y)))
	    (arctangent y x)))

    (define (tag x) (attach-tag 'polar x))
    (put 'real-part '(polar) real-part)
    (put 'imag-part '(polar) imag-part)
    (put 'magnitude '(polar) magnitude)
    (put 'angle '(polar) angle)
    (put 'make-from-real-imag 'polar
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'polar
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    'done)

  (define (install-complex-package)
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    (define (add-complex z1 z2)
      (make-from-real-imag (add (real-part z1) (real-part z2))
			   (add (imag-part z1) (imag-part z2))))
    (define (sub-complex z1 z2)
      (make-from-real-imag (sub (real-part z1) (real-part z2))
			   (sub (imag-part z1) (imag-part z2))))
    (define (mul-complex z1 z2)
      (make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			 (add (angle z1) (angle z2))))
    (define (div-complex z1 z2)
      (make-from-mag-ang (div (magnitude z1) (magnitude z2))
			 (sub (angle z1) (angle z2))))
    (define (tag z) (attach-tag 'complex z))
    (put 'add '(complex complex)
	 (lambda (z1 z2) (tag (add-complex z1 z2))))
    (put 'sub '(complex complex)
	 (lambda (z1 z2) (tag (sub-complex z1 z2))))
    (put 'mul '(complex complex)
	 (lambda (z1 z2) (tag (mul-complex z1 z2))))
    (put 'div '(complex complex)
	 (lambda (z1 z2) (tag (div-complex z1 z2))))
    (put 'make-from-real-imag 'complex
	 (lambda (x y) (tag (make-from-real-imag x y))))
    (put 'make-from-mag-ang 'complex
	 (lambda (r a) (tag (make-from-mag-ang r a))))
    (put 'equ? '(complex complex)
	 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
			    (= 0 (imag-part (sub-complex x y))))))
    (put 'equ? '(rectangular polar) equ?)
    (put 'equ? '(polar rectangular) equ?)
    (put 'zero? '(complex)
	 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
    (put 'project '(complex) (lambda (z) (real-part z)))
    'done)

  (define (make-complex-from-real-imag x y)
    ((get 'make-from-real-imag 'complex) x y))

  (define (make-complex-from-mag-ang r a)
    ((get 'make-from-mag-ang 'complex) r a))

  (install-rectangular-package)
  (install-polar-package)
  (install-rational-package)
  (install-scheme-number-package)
  (install-complex-package)

  (put 'real-part '(complex) real-part)
  (put 'imag-part '(complex) imag-part)
  (put 'magnitude '(complex) magnitude)
  (put 'angle '(complex) angle)

  (define (apply-generic op . args)
    (define (all-argtypes-same? . args)
      (let ((type (type-tag (car args))))
	(accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
    (define (coercion-if-exists? type arg-tags)
      (let ((coercion-list (map (lambda (x) 
				  (if (eq? type x)
				      identity
				      (get-coercion x type))) arg-tags)))
	(if (accumulate (lambda (x y) (and x y)) #t coercion-list)
	    coercion-list
	    #f)))
    (drop (let* ((type-tags (map type-tag args))
		 (proc (get op type-tags)))
	    (cond (proc (apply proc (map contents args)))
		  ((= 1 (length args))
		   #;(show #t "No proc found for op=" op ", type-tags=" type-tags "\n")
		   (apply-generic op (raise-type (car args))))
		  ((= 2 (length args))
		   (if (type1<=type2? (car type-tags) (cadr type-tags))
		       (apply-generic op (raise-type (car args)) (cadr args))
		       (apply-generic op (car args)  (raise-type (cadr args)))))
		  ((and (>= (length args) 2) (not (all-argtypes-same? args)))
		   (let types-loop ((types type-tags))
		     (let ((list-of-coercion-functions
			    (coercion-if-exists? (car types) type-tags)))
		       (if list-of-coercion-functions
			   (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
							      list-of-coercion-functions
							      args)))
			   (if (not (null? (cdr types)))
			       (types-loop (cdr types))
			       (error "apply-generic:Even coercions failed. No method for these types."))))))
		  (else (error "apply-generic:No method for these types"
			       (list op type-tags)))))))
  (define (scheme-number->complex n)
    (make-complex-from-real-imag (contents n) 0))
  (put-coercion 'scheme-number
		'complex
		scheme-number->complex)

  (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
						    (max (magnitude z1) (magnitude z2) (magnitude z3))))
  (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
  (define (identity x) x)

  (define numeric-tower (list 'integer 'rational 'scheme-number 'complex))

  (define (higher-type x)
    (define (find-higher-type x types)
      (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x))
	    ((eq? x (car types)) (cadr types))
	    (else (find-higher-type x (cdr types)))))
    (find-higher-type x numeric-tower))

  (define (type1<=type2? type1 type2)
    (if (not (memq type1 numeric-tower))
	(error "Type 1 not in the numeric tower"))
    (if (not (memq type2 numeric-tower))
	(error "Type 2 not in the numeric tower"))
    (let loop ((types numeric-tower))
      (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
	    ((eq? (car types) type1) #t)
	    ((eq? (car types) type2) #f)
	    (else (loop (cdr types))))))

  (define (integer->rational x)
    (make-rational x 1))

  (define (rational->scheme-number x)
    (make-scheme-number ((get 'to-real '(rational)) x)))
  (put-coercion 'integer 'rational integer->rational)
  (put-coercion 'rational 'scheme-number rational->scheme-number)

  (define (raise-type x)
    (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
      (if converter
	  (converter x)
	  (error "No coercion found for x" (type-tag x) x))))


  (define (remainder-integer a b)
    (when (or (not (integer? a)) (not (integer? b)))
      (error "Arguments must be integers" a b))
    (remainder a b))

  (put 'remainder '(integer integer) remainder-integer)
  (define (remainder-generalized a b) (apply-generic 'remainder a b))

  (define (project obj)
    (apply-generic 'project obj))
  (define (droppable? obj)
    (cond ((not (memq (type-tag obj) numeric-tower)) #f)
	  ((eq? (type-tag obj) (car numeric-tower)) #f)
	  ((equ? obj (raise-type (project obj))) #t)
	  (else #f)))
  (define (drop obj) 
    (if (droppable? obj)
	(drop (project obj))
	obj))

  (show #t "Test 1: Subtracting complex numbers: "
	(sub
	 (make-complex-from-real-imag 1.1 2)
	 (make-complex-from-real-imag 0 2)) "\n")
  (define (install-polynomial-package)
    (define (make-poly variable term-list)
      (cons variable term-list))
    (define (variable p) (car p))
    (define (term-list p)
      (cdr p))
    (define (variable? x) (symbol? x))
    (define (same-variable? v1 v2)
      (and (variable? v1) (variable? v2) (eq? v1 v2)))
    (define (=number? exp num)
      (and (number? exp) (= exp num)))
    (define (the-empty-termlist) '())

    (define (rest-terms term-list) (cdr term-list))
    (define (empty-termlist? term-list) (null? term-list))

    (define (make-term order coeff) (list order coeff))
    (define (order term) (car term))
    (define (coeff term) (cadr term))

    #;(continued on next page)

    (define (add-poly p1 p2)
      (if (same-variable? (variable p1) (variable p2))
	  (make-poly (variable p1)
		     (add-terms (term-list p1)
				(term-list p2)))
	  (error "Polys not in same var -- ADD-POLY"
		 (list p1 p2))))
    (define (sub-poly p1 p2)
      (add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
    (define (add-terms L1 L2)
      (cond ((empty-termlist? L1) L2)
	    ((empty-termlist? L2) L1)
	    (else
	     (let ((t1 (first-term L1)) (t2 (first-term L2)))
	       (cond ((> (order t1) (order t2))
		      (adjoin-term
		       t1 (add-terms (rest-terms L1) L2)))
		     ((< (order t1) (order t2))
		      (adjoin-term
		       t2 (add-terms L1 (rest-terms L2))))
		     (else
		      (adjoin-term
		       (make-term (order t1)
				  (add (coeff t1) (coeff t2)))
		       (add-terms (rest-terms L1)
				  (rest-terms L2)))))))))


    (define (mul-poly p1 p2)
      (if (same-variable? (variable p1) (variable p2))
	  (make-poly (variable p1)
		     (mul-terms (term-list p1)
				(term-list p2)))
	  (error "Polys not in same var -- MUL-POLY"
		 (list p1 p2))))
    (define (div-poly p1 p2)
      (if (same-variable? (variable p1) (variable p2))
	  (let ((quotient-and-remainder (div-terms (term-list p1)
						   (term-list p2))))
	    (list (make-poly (variable p1) (car  quotient-and-remainder))
		  (make-poly (variable p1) (cadr quotient-and-remainder))))
	    (error "div-poly: Polys not in the same var" p1 p2)))
    (define (div-terms L1 L2)
	    (if (empty-termlist? L1)
		(list (the-empty-termlist) (the-empty-termlist))
		(let ((t1 (first-term L1))
		      (t2 (first-term L2)))
		  (if (> (order t2) (order t1))
		      (list (the-empty-termlist) L1)
		      (let ((new-c (div (coeff t1) (coeff t2)))
			    (new-o (- (order t1) (order t2))))
			(let ((rest-of-result (div-terms (term-list
							  (sub-poly
							   (make-poly 'fake-var L1)
							   (mul-poly
							    (make-poly 'fake-var (list (make-term new-o new-c)))
							    (make-poly 'fake-var L2))))
							 L2)
					      ))
			  (show #t "div-terms: rest-of-result: " (displayed rest-of-result) "\n")
			  (list (adjoin-term (make-term new-o new-c) (car rest-of-result)) (cadr rest-of-result))
			  ))))))
    (define (mul-terms L1 L2)
      (if (empty-termlist? L1)
	  (the-empty-termlist)
	  (add-terms (mul-term-by-all-terms (first-term L1) L2)
		     (mul-terms (rest-terms L1) L2))))

    (define (mul-term-by-all-terms t1 L)
      (if (empty-termlist? L)
	  (the-empty-termlist)
	  (let ((t2 (first-term L)))
	    (adjoin-term
	     (make-term (+ (order t1) (order t2))
			(mul (coeff t1) (coeff t2)))
	     (mul-term-by-all-terms t1 (rest-terms L))))))
    (define (zero-poly? poly)
      #;(show #t "zero-poly?: poly=" (displayed poly) "\n")
      (cond ((empty-termlist? (term-list poly)) #t)
	    ((not (= 0 (coeff (first-term (term-list poly))))) #f)
	    (else (zero-poly? 
		   (make-poly (variable poly)
			      (rest-terms (term-list poly)))))))
    (define (tag p) (attach-tag 'polynomial p))
    (define (termlist-type-of term-list)
      #;(show #t "t-t-o: term-list=" (displayed term-list) "\n")
      (cond ((null? term-list) 'sparse)
	    ((pair? (car term-list)) 'sparse)
	    ((list? term-list) 'dense)
	    (else (error "Unknown type of list" term-list))))
    (define (adjoin-term term term-list)
      ((get 'adjoin-term (termlist-type-of term-list)) term term-list))
    (define (first-term term-list)
      #;(show #t "first-term: term-list=" (displayed term-list) "\n")
      #;(show #t "first-term: term-list-type=" (displayed (termlist-type-of term-list)) "\n")
      ((get 'first-term (termlist-type-of term-list)) term-list))
    (put 'add '(polynomial polynomial)
	 (lambda (p1 p2) (tag (add-poly p1 p2))))
    (put 'mul '(polynomial polynomial)
	 (lambda (p1 p2) (tag (mul-poly p1 p2))))
    (put 'sub '(polynomial polynomial)
	 (lambda (p1 p2) (tag (sub-poly p1 p2))))
    (put 'make 'polynomial
	 (lambda (var terms) (tag (make-poly var terms))))
    (put 'zero? '(polynomial) zero-poly?)
    (put 'div '(polynomial polynomial) div-poly)
    'done)
  (install-polynomial-package)

  (define (install-polynomial-sparse-package)
    (define (coeff term) (cadr term))
    (define (first-term-sparse term-list) (car term-list))
    (define (adjoin-term-sparse term term-list)
      (if (zero? (coeff term))
	  term-list
	  (cons term term-list)))
    (put 'adjoin-term 'sparse adjoin-term-sparse)
    (put 'first-term 'sparse first-term-sparse)
    'done)
  (install-polynomial-sparse-package)

  (define (install-polynomial-dense-package)
    (define (make-term order coeff) (list order coeff))
    (define (order term) (car term))
    (define (coeff term) (cadr term))

    (define (adjoin-term-dense term term-list)
	(if (zero? (coeff term))
	    term-list
	    (if (> (order term) (length term-list))
		(append (list (coeff term))
			(make-list (- (order term) (length term-list)) 0)
			term-list)
		(error "adjoin-term:Appending a smaller order term. Recheck."))))
    (define (first-term-dense term-list) 
       #;(show #t "first-term-dense: " (displayed (make-term (car term-list) (length (cdr term-list)))) "\n")
       (make-term (length (cdr term-list)) (car term-list) ))
    (put 'adjoin-term 'dense adjoin-term-dense)
    (put 'first-term 'dense first-term-dense)
    'done)
  (install-polynomial-dense-package)

  (define (make-polynomial var terms)
    ((get 'make 'polynomial) var terms))
  (show #t "Test 2: Making polynomials: " 
	(make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
  (show #t "Test 3: Zero?: " 
	(zero? (make-polynomial 'x (list (list 5 1) (list 4 2)))) "\n")
  (show #t "Test 4: Adding polynomials: "
	(add (make-polynomial 'x '((5 1) (4 2) (0 1)))
	     (make-polynomial 'x '((5 1)))) "\n")
  #;(show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

  (show #t "Test 5: Subtracting polynomials: "
	(sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
	     (make-polynomial 'x '((0 1)))) "\n")

  (show #t "Test 6: Making a dense polynomial: " (make-polynomial 'x '(1 2 3 4 5)) "\n")
  (show #t "Test 7: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(0)))) "\n")
  (show #t "Test 8: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(1)))) "\n")
  (show #t "Test 9: Adding dense polynomials: "
	(add (make-polynomial 'x '(1 2 0 0 0 1))
	     (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
  (show #t "Test10: Subtracting dense polynomials: "
	(sub (make-polynomial 'x '(1 2 0 0 0 1))
	     (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
  (show #t "Test11: Subtracting dense and sparse polynomials: "
	(sub (make-polynomial 'x '(1 2 0 0 0 1))
	     (make-polynomial 'x '((4 2)))) "\n")
  (show #t "Test12: Dividing x^2 + 2x + 1 by x+1: "
	(displayed
	 (div (make-polynomial 'x '((2 1) (1 2) (0 1)))
	      (make-polynomial 'x '(      (1 1) (0 1)))) ) "\n")
#+end_src

#+RESULTS:
#+begin_example
Test 1: Subtracting complex numbers: (rational 2476979795053773 . 2251799813685248)
Test 2: Making polynomials: (polynomial x (5 1) (4 2))
Test 3: Zero?: #f
Test 4: Adding polynomials: (polynomial x (5 2) (4 2) (0 1))
Test 5: Subtracting polynomials: (polynomial x (5 1) (4 2))
Test 6: Making a dense polynomial: (polynomial x 1 2 3 4 5)
Test 7: zero? dense polynomial: #t
Test 8: zero? dense polynomial: #f
Test 9: Adding dense polynomials: (polynomial x (5 2) (4 2) (0 1))
Test10: Subtracting dense polynomials: (polynomial x 2 0 0 0 1)
Test11: Subtracting dense and sparse polynomials: (polynomial x 1 0 0 0 0 1)
div-terms: rest-of-result: (() ())
div-terms: rest-of-result: (((0 1)) ())
Test12: Dividing x^2 + 2x + 1 by x+1: ((x (1 1) (0 1)) (x))
#+end_example

This task also wasn't very difficult. The only problem here is that
~div-poly~ returns two polynomials, not one. This is a problem, because this
breaks the closure property.

*** DONE Exercise 2.92 Ordering of variables so that addition and multiplication work for different variables
    CLOSED: [2019-10-27 Sun 13:32]

"This is not easy, Prof. Abelson". Indeed, at the very beginning we are
meeting a problem: we need to add polynomials and numbers. This problem seems
to be extraordinarily laborious.

Well, the sketch of the idea was to rearrange the polynomials to a canonical
form, so that the variables are ordered sequentially. So we will need a way
to compare the variables, say, alphabetically.

To help us in this business, we shall use R^7 RS standard procedures
~symbol->string~ and ~string<?~.

Essentially, this code does a bubble-sort on the variables. The
~normalize-once~ procedure makes one pass of the exchanges, that is, it
effectively allows one "bubble" to float up.

The ~normalize-fully~ procedure repeats the normalization until it's done,
which may lead to infinite loops in case there are some bugs inside, but it
should work as \(n^2\) .

The thing that does not work in this implementation is the division of
polynomials of different variables. To be hones, because I am not sure what
it is semantically.

In total, this exercise took me several days, and the net amount of hours
spent is about 10.

#+begin_src scheme :exports both :results output
  (define (thingy-source thingy)
    (cond ((lambda? thingy) (list "lambda" (lambda-source thingy)))
	  ((procedure? thingy) (list "procedure" (procedure-name thingy)))
	  ((pair? thingy) (list "pair" (pair-source thingy)))
	  (else "No source? refactor")))

    (define (accumulate op initial sequence)
      (if (null? sequence)
	  initial
	  (accumulate op (op initial (car sequence)) (cdr sequence))))
    (define false #f)
    (define true  #t)
    (define (make-table)
      (let ((local-table (list '*table*)))
	(define (lookup key-1 key-2)
	  (let ((subtable (assoc key-1 (cdr local-table))))
	    (if subtable
		(let ((record (assoc key-2 (cdr subtable))))
		  (if record
		      (cdr record)
		      false))
		false)))
	(define (insert! key-1 key-2 value)
	  (let ((subtable (assoc key-1 (cdr local-table))))
	    (if subtable
		(let ((record (assoc key-2 (cdr subtable))))
		  (if record
		      (set-cdr! record value)
		      (set-cdr! subtable
				(cons (cons key-2 value)
				      (cdr subtable)))))
		(set-cdr! local-table
			  (cons (list key-1
				      (cons key-2 value))
				(cdr local-table)))))
	  'ok)
	(define (dispatch m)
	  (cond ((eq? m 'lookup-proc) lookup)
		((eq? m 'insert-proc!) insert!)
		(else (error "Unknown operation -- TABLE" m))))
	dispatch))

    (define operation-table (make-table))
    (define get (operation-table 'lookup-proc))
    (define put (operation-table 'insert-proc!))

    (define coercion-table (make-table))
    (define get-coercion (coercion-table 'lookup-proc))
    (define put-coercion (coercion-table 'insert-proc!))

    (define (attach-tag type-tag contents)
      (cons type-tag contents))

    (define (type-tag datum)
      (cond ((pair? datum) (car datum))
	    ((exact-integer? datum) 'integer)
	    ((real? datum) 'scheme-number)
	    (error "Bad tagged datum -- TYPE-TAG" datum)))

  (define (contents datum)
      (cond ((pair? datum) (cdr datum))
	    ((integer? datum) datum)
	    ((real? datum) datum)
	    (else (error "Bad tagged datum -- CONTENTS" datum))))

    (define (integer? x)
      (eq? (type-tag x) 'integer))
    (define (rectangular? z)
      (eq? (type-tag z) 'rectangular))

    (define (polar? z)
      (eq? (type-tag z) 'polar))


    (define (real-part z) (apply-generic 'real-part z))
    (define (imag-part z) (apply-generic 'imag-part z))
    (define (magnitude z) (apply-generic 'magnitude z))
    (define (angle z) (apply-generic 'angle z))

    (define (add x y) (apply-generic 'add x y))
    (define (sub x y) (apply-generic 'sub x y))
    (define (mul x y) (apply-generic 'mul x y))
    (define (div x y) (apply-generic 'div x y))

    (define (equ? x y)
      (apply-generic 'equ? x y))
    (define (zero? x) (apply-generic 'zero? x))

    (define (exp x y) (apply-generic 'exp x y))

    (define (install-scheme-number-package)
      (define (tag x)
	(attach-tag 'scheme-number x))
      (put 'add '(scheme-number scheme-number)
	   (lambda (x y) (tag (+ x y))))
      (put 'sub '(scheme-number scheme-number)
	   (lambda (x y) (tag (- x y))))
      (put 'mul '(scheme-number scheme-number)
	   (lambda (x y) (tag (* x y))))
      (put 'div '(scheme-number scheme-number)
	   (lambda (x y) (tag (/ x y))))
      (put 'make 'scheme-number
	   (lambda (x) (tag x)))
      (put 'equ? '(scheme-number scheme-number)
	   (lambda (x y) (= x y)))
      (put 'zero? '(scheme-number)
	   (lambda (x) (= 0 x)))
      (put 'exp '(scheme-number scheme-number)
	   (lambda (x y) (tag (expt x y))))
      (put 'project '(scheme-number)
	   (lambda (x)
	     (make-rational
	      (exact (numerator x))
	      (exact (denominator x)))))
      (put 'sine '(scheme-number) sin)
      (put 'cosine '(scheme-number) cos)
      (put 'square-root '(scheme-number) sqrt)
      (put 'arctangent '(schemer-number) atan)
      'done)

    (define (sine x) (apply-generic 'sine x))
    (define (cosine x) (apply-generic 'cosine x))
    (define (square-root x) (apply-generic 'square-root x))
    (define (arctangent x) (apply-generic 'arctangent x))

    (define (make-scheme-number n)
      ((get 'make 'scheme-number) n))

    (define (install-rational-package)
      (define (numer x) (car x))
      (define (denom x) (cdr x))
      (define (make-rat n d)
	(let ((g (gcd n d)))
	  (cons (/ n g) (/ d g))))
      (define (add-rat x y)
	(make-rat (+ (* (numer x) (denom y))
		     (* (numer y) (denom x)))
		  (* (denom x) (denom y))))
      (define (sub-rat x y)
	(make-rat (- (* (numer x) (denom y))
		     (* (numer y) (denom x)))
		  (* (denom x) (denom y))))
      (define (mul-rat x y)
	(make-rat (* (numer x) (numer y))
		  (* (denom x) (denom y))))
      (define (div-rat x y)
	(make-rat (* (numer x) (denom y))
		  (* (denom x) (numer y))))

      (define (tag x) (attach-tag 'rational x))
      (put 'add '(rational rational)
	   (lambda (x y) (tag (add-rat x y))))
      (put 'sub '(rational rational)
	   (lambda (x y) (tag (sub-rat x y))))
      (put 'mul '(rational rational)
	   (lambda (x y) (tag (mul-rat x y))))
      (put 'div '(rational rational)
	   (lambda (x y) (tag (div-rat x y))))

      (put 'make 'rational
	   (lambda (n d) (tag (make-rat n d))))
      (put 'equ? '(rational rational)
	   (lambda (x y) (= 0 (numer (sub-rat x y)))))
      (put 'zero? '(rational) (lambda (x) (= 0 (numer x))))
      (put 'project '(rational) (lambda (x) 
				  (exact (truncate (/ (numer x) (denom x))))))
      (put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
      'done)

    (define (make-rational n d)
      ((get 'make 'rational) n d))

    (define (install-rectangular-package)

      (define (real-part z) (car z))
      (define (imag-part z) (cdr z))
      (define (make-from-real-imag x y) (cons x y))
      (define (magnitude z)
	(square-root (add (square (real-part z))
			  (square (imag-part z)))))
      (define (angle z)
	(arctangent (imag-part z) (real-part z)))
      (define (make-from-mag-ang r a)
	(cons (mul r (cosine a)) (mul r (sine a))))

      (define (tag x) (attach-tag 'rectangular x))
      (put 'real-part '(rectangular) real-part)
      (put 'imag-part '(rectangular) imag-part)
      (put 'magnitude '(rectangular) magnitude)
      (put 'angle '(rectangular) angle)
      (put 'make-from-real-imag 'rectangular
	   (lambda (x y) (tag (make-from-real-imag x y))))
      (put 'make-from-mag-ang 'rectangular
	   (lambda (r a) (tag (make-from-mag-ang r a))))
      'done)

    (define (install-polar-package)

      (define (magnitude z) (car z))
      (define (angle z) (cdr z))
      (define (make-from-mag-ang r a) (cons r a))
      (define (real-part z)
	(mul (magnitude z) (cosine (angle z))))
      (define (imag-part z)
	(mul (magnitude z) (sine (angle z))))
      (define (make-from-real-imag x y)
	(cons (square-root (add (square x) (square y)))
	      (arctangent y x)))

      (define (tag x) (attach-tag 'polar x))
      (put 'real-part '(polar) real-part)
      (put 'imag-part '(polar) imag-part)
      (put 'magnitude '(polar) magnitude)
      (put 'angle '(polar) angle)
      (put 'make-from-real-imag 'polar
	   (lambda (x y) (tag (make-from-real-imag x y))))
      (put 'make-from-mag-ang 'polar
	   (lambda (r a) (tag (make-from-mag-ang r a))))
      'done)

    (define (install-complex-package)
      (define (make-from-real-imag x y)
	((get 'make-from-real-imag 'rectangular) x y))
      (define (make-from-mag-ang r a)
	((get 'make-from-mag-ang 'polar) r a))
      (define (add-complex z1 z2)
	(make-from-real-imag (add (real-part z1) (real-part z2))
			     (add (imag-part z1) (imag-part z2))))
      (define (sub-complex z1 z2)
	(make-from-real-imag (sub (real-part z1) (real-part z2))
			     (sub (imag-part z1) (imag-part z2))))
      (define (mul-complex z1 z2)
	(make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			   (add (angle z1) (angle z2))))
      (define (div-complex z1 z2)
	(make-from-mag-ang (div (magnitude z1) (magnitude z2))
			   (sub (angle z1) (angle z2))))
      (define (tag z) (attach-tag 'complex z))
      (put 'add '(complex complex)
	   (lambda (z1 z2) (tag (add-complex z1 z2))))
      (put 'sub '(complex complex)
	   (lambda (z1 z2) (tag (sub-complex z1 z2))))
      (put 'mul '(complex complex)
	   (lambda (z1 z2) (tag (mul-complex z1 z2))))
      (put 'div '(complex complex)
	   (lambda (z1 z2) (tag (div-complex z1 z2))))
      (put 'make-from-real-imag 'complex
	   (lambda (x y) (tag (make-from-real-imag x y))))
      (put 'make-from-mag-ang 'complex
	   (lambda (r a) (tag (make-from-mag-ang r a))))
      (put 'equ? '(complex complex)
	   (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
			      (= 0 (imag-part (sub-complex x y))))))
      (put 'equ? '(rectangular polar) equ?)
      (put 'equ? '(polar rectangular) equ?)
      (put 'zero? '(complex)
	   (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
      (put 'project '(complex) (lambda (z) (real-part z)))
      'done)

    (define (make-complex-from-real-imag x y)
      ((get 'make-from-real-imag 'complex) x y))

    (define (make-complex-from-mag-ang r a)
      ((get 'make-from-mag-ang 'complex) r a))

    (install-rectangular-package)
    (install-polar-package)
    (install-rational-package)
    (install-scheme-number-package)
    (install-complex-package)

    (put 'real-part '(complex) real-part)
    (put 'imag-part '(complex) imag-part)
    (put 'magnitude '(complex) magnitude)
    (put 'angle '(complex) angle)

    (define (apply-generic op . args)
      #;(show #t "apply-generic:entry\n")
      #;(error "debug")
      (define (variable poly) (car poly))
      (define (all-argtypes-same? . args)
	(let ((type (type-tag (car args))))
	  (accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
      (define (coercion-if-exists? type arg-tags)
	(let ((coercion-list (map (lambda (x) 
				    (if (eq? type x)
					identity
					(get-coercion x type))) arg-tags)))
	  (if (accumulate (lambda (x y) (and x y)) #t coercion-list)
	      coercion-list
	      #f)))
      (drop (let* ((type-tags (map type-tag args))
		   (proc (get op type-tags)))
	      #;(show #t "apply-generic: type-tags=" 
		       (displayed type-tags)
		       " proc=" (written proc)
		       " proc-source=" (thingy-source proc) "\n")
	      (cond (proc (apply proc (map contents args)))
		    ((= 1 (length args))
		     #;(show #t "No proc found for op=" op ", type-tags=" type-tags ", arg=" (displayed args) "\n")
		     (apply-generic op (raise-type (car args))))
		    ((= 2 (length args))
		     (cond ((and (eq? 'polynomial (car type-tags))
			       (numeric? (cadr type-tags)))
			    (apply-generic op
					   (car args)
					   (make-polynomial (variable (contents (car args)))
							    (list (list 0 (cadr args))))))
			   ((and (numeric? (car type-tags))
			       (eq? 'polynomial (cadr type-tags)))
			    (apply-generic op
					   (make-polynomial (variable (contents (cadr args)))
							    (list (list 0 (car args))))
					   (cadr args)))			 
			   ((and (get-coercion (car type-tags) (cadr type-tags))
			       (not (eq? (car type-tags) (cadr type-tags))))
			    (apply-generic op
					   ((get-coercion
					     (car type-tags)
					     (cadr type-tags)) (car args))
					   (cadr args)))
			   ((and (get-coercion (cadr type-tags) (car type-tags))
			       (not (eq? (car type-tags) (cadr type-tags))))
			    (apply-generic op
					   (car args)
					   ((get-coercion
					     (cadr type-tags)
					     (car type-tags)) (cadr args) )))
			   ((comparable? (car type-tags) (cadr type-tags))
			    (if
			     (type1<=type2? (car type-tags) (cadr type-tags))
			     (apply-generic op (raise-type (car args)) (cadr args))
			     (apply-generic op (car args)  (raise-type (cadr args)))))
			   (else (error "apply-generic:Incomparable types: (type-tags,args)=" type-tags args))))
		    ((and (> (length args) 2) (not (all-argtypes-same? args)))
		     (let types-loop ((types type-tags))
		       (let ((list-of-coercion-functions
			      (coercion-if-exists? (car types) type-tags)))
			 (if list-of-coercion-functions
			     (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
								list-of-coercion-functions
								args)))
			     (if (not (null? (cdr types)))
				 (types-loop (cdr types))
				 (error "apply-generic:Even coercions failed. No method for these types."))))))
		    (else (error "apply-generic:No method for these types"
				 (list op type-tags)))))))
    (define (scheme-number->complex n)
      (make-complex-from-real-imag (contents n) 0))
    (put-coercion 'scheme-number
		  'complex
		  scheme-number->complex)

    (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
						      (max (magnitude z1) (magnitude z2) (magnitude z3))))
    (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
    (define (identity x) x)

  (define numeric-tower (list 'integer 'rational 'scheme-number 'complex))
  (define (comparable? type1 type2) (and (memq type1 numeric-tower) (memq type2 numeric-tower)))
  #;(define (higher-type x)
    (show #t "higher-type:x=" (displayed x) "\n")
      (define (find-higher-type x types)
	(cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x types))
	      ((eq? x (car types)) (cadr types))
	      (else (find-higher-type x (cdr types)))))
      (find-higher-type x numeric-tower))

  (define (numeric? x)
    (memq x numeric-tower))
  (define (polynomial? x)
    (eq? (type-tag x) 'polynomial))
  (define (higher-type x)
    (let ((tail (memq x numeric-tower)))
      (cond ((eq? #f tail) (error "Type not in the tower" x))
	    ((null? (cdr tail)) (error "Already the highest type:" x))
	    (else (cadr tail)))))

  (show #t "Test: Higher than 'integer: " (higher-type 'integer) "\n")
  #;(show #t "Test: Higher than 'complex: " (higher-type 'complex) "\n")

    (define (type1<=type2? type1 type2)
      (if (not (memq type1 numeric-tower))
	  (error "Type 1 not in the numeric tower"))
      (if (not (memq type2 numeric-tower))
	  (error "Type 2 not in the numeric tower"))
      (let loop ((types numeric-tower))
	(cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
	      ((eq? (car types) type1) #t)
	      ((eq? (car types) type2) #f)
	      (else (loop (cdr types))))))

    (define (integer->rational x)
      (make-rational x 1))

    (define (rational->scheme-number x)
      (make-scheme-number ((get 'to-real '(rational)) x)))
    (put-coercion 'integer 'rational integer->rational)
    (put-coercion 'rational 'scheme-number rational->scheme-number)

  (define (raise-type x)
    #;(show #t "Raising type of: " (displayed x) "\n")
      (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
	(if converter
	    (converter x)
	    (error "No coercion found for x" (type-tag x) x))))


    (define (remainder-integer a b)
      (when (or (not (integer? a)) (not (integer? b)))
	(error "Arguments must be integers" a b))
      (remainder a b))

    (put 'remainder '(integer integer) remainder-integer)
    (define (remainder-generalized a b) (apply-generic 'remainder a b))

    (define (project obj)
      (apply-generic 'project obj))
    (define (droppable? obj)
      (cond ((not (memq (type-tag obj) numeric-tower)) #f)
	    ((eq? (type-tag obj) (car numeric-tower)) #f)
	    ((equ? obj (raise-type (project obj))) #t)
	    (else #f)))
    (define (drop obj) 
      (if (droppable? obj)
	  (drop (project obj))
	  obj))

    (show #t "Test 1: Subtracting complex numbers: "
	  (sub
	   (make-complex-from-real-imag 1.1 2)
	   (make-complex-from-real-imag 0 2)) "\n")
  (define (install-polynomial-package)
    #;(define (contents generic-object)
      (cdr generic-object))
      (define (make-poly variable term-list)
	(cons variable term-list))
      (define (variable p) (car p))
      (define (term-list p)
	(cdr p))
      (define (variable? x) (symbol? x))
      (define (same-variable? v1 v2)
	(and (variable? v1) (variable? v2) (eq? v1 v2)))
      (define (=number? exp num)
	(and (number? exp) (= exp num)))
      (define (the-empty-termlist) '())

      (define (rest-terms term-list) (cdr term-list))
      (define (empty-termlist? term-list) (null? term-list))

      (define (make-term order coeff) (list order coeff))
      (define (order term) (car term))
      (define (coeff term) (cadr term))
      (define (tag p) (attach-tag 'polynomial p))
      (put 'make 'polynomial
	   (lambda (var terms) (tag (make-poly var terms))))
      #;(continued on next page)

      (define (add-poly p1 p2)
	#;(show #t "add-poly: p1=" p1 ", p2=" p2 "\n")
	(if (same-variable? (variable p1) (variable p2))
	    (make-poly (variable p1)
		       (add-terms (term-list p1)
				  (term-list p2)))
	    (let ((res (cdr (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		(add (tag p1) (tag (make-poly (variable p1) (list (make-term 0 (tag p2))))))
		(add (tag (make-poly (variable p2) (list (make-term 0 (tag p1))))) (tag p2))))))
	      #;(show #t "add-poly:result: " (displayed res) "\n") res)))

      (show #t "TestY2: poly of poly: "
	    (make-poly 'x (list
			   (make-term 3 (make-poly
					 'y (list (make-term 1 1) (make-term 0 1))))
			   (make-term 1 2)
			   (make-term 0 4))) "\n")

      (define (sub-poly p1 p2)
	(add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
      (define (add-terms L1 L2)
	(cond ((empty-termlist? L1) L2)
	      ((empty-termlist? L2) L1)
	      (else
	       (let ((t1 (first-term L1)) (t2 (first-term L2)))
		 (cond ((> (order t1) (order t2))
			(adjoin-term
			 t1 (add-terms (rest-terms L1) L2)))
		       ((< (order t1) (order t2))
			(adjoin-term
			 t2 (add-terms L1 (rest-terms L2))))
		       (else
			(adjoin-term
			 (make-term (order t1)
				    (add (coeff t1) (coeff t2)))
			 (add-terms (rest-terms L1)
				    (rest-terms L2)))))))))


      (define (mul-poly p1 p2)
	(if (same-variable? (variable p1) (variable p2))
	    (make-poly (variable p1)
		       (mul-terms (term-list p1)
				  (term-list p2)))
	    (contents (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		(mul (tag p1)
		     (make-polynomial (variable p1)
				      (adjoin-term
				       (make-term 0
						  (tag p2)) (the-empty-termlist))))
		(mul (tag p2)
		     (make-polynomial (variable p2)
				      (adjoin-term
				       (make-term 0
						  (tag p1)) (the-empty-termlist))))))
	    #;(error "Polys not in same var -- MUL-POLY"
		   (list p1 p2))))
      (define (div-poly p1 p2)
	(if (same-variable? (variable p1) (variable p2))
	    (let ((quotient-and-remainder (div-terms (term-list p1)
						     (term-list p2))))
	      (list (make-poly (variable p1) (car  quotient-and-remainder))
		    (make-poly (variable p1) (cadr quotient-and-remainder))))
	      (error "div-poly: Polys not in the same var" p1 p2)))
      (define (div-terms L1 L2)
	      (if (empty-termlist? L1)
		  (list (the-empty-termlist) (the-empty-termlist))
		  (let ((t1 (first-term L1))
			(t2 (first-term L2)))
		    (if (> (order t2) (order t1))
			(list (the-empty-termlist) L1)
			(let ((new-c (div (coeff t1) (coeff t2)))
			      (new-o (- (order t1) (order t2))))
			  (let ((rest-of-result (div-terms (term-list
							    (sub-poly
							     (make-poly 'fake-var L1)
							     (mul-poly
							      (make-poly 'fake-var (list (make-term new-o new-c)))
							      (make-poly 'fake-var L2))))
							   L2)
						))
			    #;(show #t "div-terms: rest-of-result: " (displayed rest-of-result) "\n")
			    (list (adjoin-term (make-term new-o new-c) (car rest-of-result)) (cadr rest-of-result))
			    ))))))
      (define (mul-terms L1 L2)
	(if (empty-termlist? L1)
	    (the-empty-termlist)
	    (add-terms (mul-term-by-all-terms (first-term L1) L2)
		       (mul-terms (rest-terms L1) L2))))

      (define (mul-term-by-all-terms t1 L)
	(if (empty-termlist? L)
	    (the-empty-termlist)
	    (let ((t2 (first-term L)))
	      (adjoin-term
	       (make-term (+ (order t1) (order t2))
			  (mul (coeff t1) (coeff t2)))
	       (mul-term-by-all-terms t1 (rest-terms L))))))
      (define (zero-poly? poly)
	#;(show #t "zero-poly?: poly=" (displayed poly) "\n")
	(cond ((empty-termlist? (term-list poly)) #t)
	      ((not (zero? (coeff (first-term (term-list poly))))) #f)
	      (else (zero-poly? 
		     (make-poly (variable poly)
				(rest-terms (term-list poly)))))))

      (define (termlist-type-of term-list)
	#;(show #t "t-t-o: term-list=" (displayed term-list) "\n")
	(cond ((null? term-list) 'sparse)
	      ((pair? (car term-list)) 'sparse)
	      ((list? term-list) 'dense)
	      (else (error "Unknown type of list" term-list))))
      (define (adjoin-term term term-list)
	((get 'adjoin-term (termlist-type-of term-list)) term term-list))
      (define (first-term term-list)
	((get 'first-term (termlist-type-of term-list)) term-list))
      (define (variable_1-order<variable_2-order variable_1 variable_2)
	#;(show #t "var_1-..: variable_1=" variable_1 " variable_2=" variable_2 "\n")
	#;(show #t "var12string=" (symbol->string variable_1) "var22string=" (symbol->string variable_2) "\n")
	(string<=? (symbol->string variable_1) (symbol->string variable_2)))
      (define (normalize-fully poly)
	(if (normal-polynomial? poly)
	    poly
	    (normalize-fully (normalize-once poly))))
      (put 'add '(polynomial polynomial)
	   (lambda (p1 p2) 
	     #;(show #t "generic-add-poly:Polynomial dispatch found: p1="
		    (displayed p1) " p2=" (displayed p2) "\n")
	     (normalize-fully (tag (add-poly p1 p2)))))
      (put 'mul '(polynomial polynomial)
	   (lambda (p1 p2) (normalize-fully (tag (mul-poly p1 p2)))))
      (put 'sub '(polynomial polynomial)
	   (lambda (p1 p2) (tag (sub-poly p1 p2))))

      (put 'zero? '(polynomial) zero-poly?)
      (put 'div '(polynomial polynomial) div-poly)
      #;(put-coercion 'rational 'scheme-number rational->scheme-number)
      (define (monomial-flip-variables monomial)
	#;(show #t "m-f-v: monomial=" monomial "\n")
	(let* ((mono (contents monomial))
	       (inner-polynomial (contents (coeff (first-term (term-list mono)))))
	       (inner-poly (contents inner-polynomial))
	       (outer-order (order (first-term (term-list mono))))
	       (outer-var (variable mono))
	       (inner-var (variable inner-polynomial))
	       (inner-term-list (term-list inner-poly)))
	  #;(show #t "m-f-v: inner-poly=" inner-poly "\n")
	  (if (same-variable? inner-var outer-var)
	      (mul
	       (make-polynomial outer-var (adjoin-term (make-term outer-order 1) (the-empty-termlist)))
	       (tag inner-polynomial))
	      (tag (make-poly inner-var
			      (mul-term-by-all-terms (make-term
						      0
						      (make-polynomial
						       outer-var
						       (list (make-term
							      outer-order
							      1)))) inner-poly))))))
      #;(show #t "TestXX: sorting variables: Is 'x < 'y?: "
	    (variable_1-order<variable_2-order 'x 'y) "\n")
      #;(show #t "TestXX: sorting variables: Is 'z < 'y?: "
	    (variable_1-order<variable_2-order 'z 'y) "\n")
      #;(show #t "TestXX: (adding two basic poly): "
	    (add (make-polynomial 'x (list (make-term 1 2) (make-term 0 4)))
		 (make-polynomial 'y (list (make-term 2 3) (make-term 0 5)))) "\n")

      (define (polynomial->sum-of-first-and-rest poly)
	#;(show #t "p->s-o-f-a-r: " (displayed poly) "\n")
	(if (zero? poly)
	    poly
	    (let* ((poly1 (contents poly))
		   (first-monomial (tag
				    (make-poly
				     (variable poly1)
				     (list (first-term (term-list poly1)))))))
	      #;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
	      (add
		first-monomial
		(polynomial->sum-of-first-and-rest
		 (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))
    
      (show #t "Test13: Expanding a polynomial as monomials: "
	    (displayed
	     (polynomial->sum-of-first-and-rest
	      (make-polynomial 'y
			       (list (make-term 2 (make-polynomial
						   'x
						   (list (make-term 2 1) (make-term 0 1))))
				     (make-term 0 2))))) "\n")

      (show #t "\nTest20: start monomial: "
	    (displayed (make-polynomial 'x
					(list
					 (make-term
					  2
					  (make-polynomial
					   'y
					   (list
					    (make-term 2 1) (make-term 0 1))))))) "\n")
      (show #t "Test20: Flipping a monomial variable: "
	    (displayed
	     (monomial-flip-variables
	      (make-polynomial 'x
			       (list (make-term 1 (make-polynomial
						   'y
						   (list
						    (make-term 2 1)
						    (make-term 0 1)))))))) "\n\n")
    
    
      (define (normal-polynomial? poly)
	#;(show #t "n-p?: poly=" poly "\n")
	(cond ((not (polynomial? poly)) #t)
	      ((null? (term-list (contents poly))) #t)
	      (else (let* ((poly1 (contents poly))
			   (outer-var (variable poly1)))
		      #;(show #t "Inner-let: outer-var=" (displayed outer-var) "\n")
		      (let loop ((terms (term-list poly1)))
			#;(show #t "n-p?-loop: terms=" (displayed terms) "\n")
			(cond ((null? terms) #t)
			      ((not (polynomial? (coeff (first-term terms)))) (loop (rest-terms terms)))
			      ((not (variable_1-order<variable_2-order 
				   outer-var
				   (variable (contents (coeff (first-term terms)))))) (begin #;(show #t "wrong variable order \n") #f))
			      ((not (normal-polynomial? (coeff (first-term terms)))) (begin #;(show #t "not normal poly\n") #f))
			      (else (loop (rest-terms terms)))))
		      ))))
      (define (normalize-once poly)
	#;(show #t "normalize-once poly= " (displayed poly) "\n")
	(if (zero? poly)
	    poly
	    (let* ((poly1 (contents poly))
		   (first-monomial (tag
				    (make-poly
				     (variable poly1)
				     (list (make-term
					    (order (first-term (term-list poly1)))
					    (if (polynomial? (coeff (first-term (term-list poly1))))
						(normalize-once (coeff (first-term (term-list poly1))))
						(coeff (first-term (term-list poly1))))))))))
	      #;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
	      (add
	       (if (and (polynomial?
		       (coeff
			(first-term
			 (term-list
			  (contents first-monomial)))))
		      (variable_1-order<variable_2-order
		       (variable
			(contents
			 (coeff
			  (first-term
			   (term-list
			    (contents first-monomial))))))
		       (variable
			(contents first-monomial))))
		   (monomial-flip-variables first-monomial)
		   first-monomial)
		(polynomial->sum-of-first-and-rest
		 (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

      (show #t "Test21: normal-polynomial?:start: " (displayed (make-polynomial 'y
					     (list (make-term 2 (make-polynomial
								 'x
						   (list (make-term 2 1) (make-term 0 1))))
						   (make-term 0 2)))) "\n")
      (show #t "Test21: normal-polynomial?:result:" (normal-polynomial? (make-polynomial 'y
					     (list (make-term 2 (make-polynomial
								 'x
						   (list (make-term 2 1) (make-term 0 1))))
						   (make-term 0 2)))) "\n")
      (show #t "Test22: normal-polynomial?-good:start: "
	    (displayed
	     (make-polynomial 'x
			      (list (make-term 2 (make-polynomial
						  'y
						  (list (make-term 2 1) (make-term 0 1))))
				    (make-term 0 2)))) "\n")
      (show #t "Test22: normal-polynomial?-good:result:"
	    (normal-polynomial?
	     (make-polynomial 'x
			      (list (make-term 2 (make-polynomial
						  'y
						  (list (make-term 2 1) (make-term 0 1))))
				    (make-term 0 2)))) "\n")
    
      (show #t "Test23:input: normalizing a bad polynomial: "
	    (make-polynomial 'y
			       (list (make-term 2 (make-polynomial
						   'x
						   (list (make-term 2 1) (make-term 0 1))))
				     (make-term 0 2))) "\n")
      (show #t "Test23:result: normalizing a bad polynomial: "
	    (normalize-once (make-polynomial 'y
					     (list (make-term 2 (make-polynomial
								 'x
						   (list (make-term 2 1) (make-term 0 1))))
						   (make-term 0 2)))) "\n")
      (show #t "Test24:input: normalizing a bad polynomial: "
	    (make-polynomial 'x
			       (list (make-term 2 (make-polynomial
						   'x
						   (list (make-term 2 1) (make-term 0 1))))
				     (make-term 0 2))) "\n")
      (show #t "Test24:result: normalizing a bad polynomial: "
	    (normalize-once (make-polynomial 'x
					     (list (make-term 2 (make-polynomial
								 'x
						   (list (make-term 2 1) (make-term 0 1))))
						   (make-term 0 2)))) "\n")
    
    
      (show #t "Test24:input: normalize-fully a bad polynomial: "
	    (make-polynomial 'y
			       (list (make-term 2 (make-polynomial
						   'x
						   (list (make-term 2 1) (make-term 0 1))))
				     (make-term 0 2))) "\n")
      (show #t "Test24:result: normalize-fully a bad polynomial: "
	    (normalize-fully (make-polynomial 'y
					     (list (make-term 2 (make-polynomial
								 'x
						   (list (make-term 2 1) (make-term 0 1))))
						   (make-term 0 2)))) "\n")
    

    
      'done)


    (define (install-polynomial-sparse-package)
      (define (coeff term) (cadr term))
      (define (first-term-sparse term-list) (car term-list))
      (define (adjoin-term-sparse term term-list)
	(if (zero? (coeff term))
	    term-list
	    (cons term term-list)))
      (put 'adjoin-term 'sparse adjoin-term-sparse)
      (put 'first-term 'sparse first-term-sparse)
      'done)
    (install-polynomial-sparse-package)

    (define (install-polynomial-dense-package)
      (define (make-term order coeff) (list order coeff))
      (define (order term) (car term))
      (define (coeff term) (cadr term))

      (define (adjoin-term-dense term term-list)
	  (if (zero? (coeff term))
	      term-list
	      (if (> (order term) (length term-list))
		  (append (list (coeff term))
			  (make-list (- (order term) (length term-list)) 0)
			  term-list)
		  (error "adjoin-term:Appending a smaller order term. Recheck."))))
      (define (first-term-dense term-list) 
	 #;(show #t "first-term-dense: " (displayed (make-term (car term-list) (length (cdr term-list)))) "\n")
	 (make-term (length (cdr term-list)) (car term-list) ))
      (put 'adjoin-term 'dense adjoin-term-dense)
      (put 'first-term 'dense first-term-dense)
      'done)
    #;(install-polynomial-dense-package)

    (define (make-polynomial var terms)
      ((get 'make 'polynomial) var terms))

  (install-polynomial-package)


    #;(show #t "Test 2: Making polynomials: " 
	  (make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
    #;(show #t "Test 3: Zero?: " 
	  (zero? (make-polynomial 'x (list (list 5 1) (list 4 2)))) "\n")
    #;(show #t "Test 4: Adding polynomials: "
	  (add (make-polynomial 'x '((5 1) (4 2) (0 1)))
	       (make-polynomial 'x '((5 1)))) "\n")
    #;(show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

    #;(show #t "Test 5: Subtracting polynomials: "
	  (sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
	       (make-polynomial 'x '((0 1)))) "\n")

    #;(show #t "Test 6: Making a dense polynomial: " (make-polynomial 'x '(1 2 3 4 5)) "\n")
    #;(show #t "Test 7: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(0)))) "\n")
    #;(show #t "Test 8: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(1)))) "\n")
    #;(show #t "Test 9: Adding dense polynomials: "
	  (add (make-polynomial 'x '(1 2 0 0 0 1))
	       (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
    #;(show #t "Test10: Subtracting dense polynomials: "
	  (sub (make-polynomial 'x '(1 2 0 0 0 1))
	       (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
    #;(show #t "Test11: Subtracting dense and sparse polynomials: "
	  (sub (make-polynomial 'x '(1 2 0 0 0 1))
	       (make-polynomial 'x '((4 2)))) "\n")
    #;(show #t "Test12: Dividing x^2 + 2x + 1 by x+1: "
	  (displayed
	   (div (make-polynomial 'x '((2 1) (1 2) (0 1)))
		(make-polynomial 'x '(      (1 1) (0 1)))) ) "\n")
    #;(show #t "Test14: Adding polynomials of two variables: "
	  (displayed
	   (add (make-polynomial 'x '((1 1)))
		(make-polynomial 'y '((1 1))))))
    #;(show #t "Test14: Adding polynomials of two variables, when one of them is nonexistant: "
	  (displayed
	   (add (make-polynomial 'x '((1 1)))
		(make-polynomial 'y '((0 1))))))
  (show #t "Test25: multiplying different variables: "
	(displayed (mul (make-polynomial 'x '((1 1)))
			(make-polynomial 'y '((1 1))))) "\n")


#+end_src

#+RESULTS:
#+begin_example
Test: Higher than 'integer: rational
Test 1: Subtracting complex numbers: (rational 2476979795053773 . 2251799813685248)
TestY2: poly of poly: (x (3 (y (1 1) (0 1))) (1 2) (0 4))
Test13: Expanding a polynomial as monomials: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))

Test20: start monomial: (polynomial x (2 (polynomial y (2 1) (0 1))))
Test20: Flipping a monomial variable: (polynomial y (2 (polynomial x (1 1))) (0 (polynomial x (1 1))))

Test21: normal-polynomial?:start: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test21: normal-polynomial?:result:#f
Test22: normal-polynomial?-good:start: (polynomial x (2 (polynomial y (2 1) (0 1))) (0 2))
Test22: normal-polynomial?-good:result:#t
Test23:input: normalizing a bad polynomial: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test23:result: normalizing a bad polynomial: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))
Test24:input: normalizing a bad polynomial: (polynomial x (2 (polynomial x (2 1) (0 1))) (0 2))
Test24:result: normalizing a bad polynomial: (polynomial x (4 1) (2 1) (0 2))
Test24:input: normalize-fully a bad polynomial: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test24:result: normalize-fully a bad polynomial: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))
Test25: multiplying different variables: (polynomial x (1 (polynomial y (1 1))))
#+end_example

*** DONE Exercise 2.93 Rational polynomials
    CLOSED: [2019-10-27 Sun 22:36]

I do not have any other choice rather than copy everything again.  

This turned out to be quite an easy exercise. The architectural decision was
to stop using rational numbers entirely and remove them from the numeric
tower. In principle, rationals can be added as a super-type of polynomials,
but so far this has not been requested. 

Note that the normalization algorithm developed in the Exercise 2.92 is still
hooked into the system, even though it would only be used for the case when
the "inner" and "outer" polynomials are of the same variable.

#+begin_src scheme :exports both :results output
    (define (thingy-source thingy)
      (cond ((lambda? thingy) (list "lambda" (lambda-source thingy)))
	    ((procedure? thingy) (list "procedure" (procedure-name thingy)))
	    ((pair? thingy) (list "pair" (pair-source thingy)))
	    (else "No source? refactor")))

      (define (accumulate op initial sequence)
	(if (null? sequence)
	    initial
	    (accumulate op (op initial (car sequence)) (cdr sequence))))
      (define false #f)
      (define true  #t)
      (define (make-table)
	(let ((local-table (list '*table*)))
	  (define (lookup key-1 key-2)
	    (let ((subtable (assoc key-1 (cdr local-table))))
	      (if subtable
		  (let ((record (assoc key-2 (cdr subtable))))
		    (if record
			(cdr record)
			false))
		  false)))
	  (define (insert! key-1 key-2 value)
	    (let ((subtable (assoc key-1 (cdr local-table))))
	      (if subtable
		  (let ((record (assoc key-2 (cdr subtable))))
		    (if record
			(set-cdr! record value)
			(set-cdr! subtable
				  (cons (cons key-2 value)
					(cdr subtable)))))
		  (set-cdr! local-table
			    (cons (list key-1
					(cons key-2 value))
				  (cdr local-table)))))
	    'ok)
	  (define (dispatch m)
	    (cond ((eq? m 'lookup-proc) lookup)
		  ((eq? m 'insert-proc!) insert!)
		  (else (error "Unknown operation -- TABLE" m))))
	  dispatch))

      (define operation-table (make-table))
      (define get (operation-table 'lookup-proc))
      (define put (operation-table 'insert-proc!))

      (define coercion-table (make-table))
      (define get-coercion (coercion-table 'lookup-proc))
      (define put-coercion (coercion-table 'insert-proc!))

      (define (attach-tag type-tag contents)
	(cons type-tag contents))

      (define (type-tag datum)
	(cond ((pair? datum) (car datum))
	      ((exact-integer? datum) 'integer)
	      ((real? datum) 'scheme-number)
	      (error "Bad tagged datum -- TYPE-TAG" datum)))

    (define (contents datum)
	(cond ((pair? datum) (cdr datum))
	      ((integer? datum) datum)
	      ((real? datum) datum)
	      (else (error "Bad tagged datum -- CONTENTS" datum))))

      (define (integer? x)
	(eq? (type-tag x) 'integer))
      (define (rectangular? z)
	(eq? (type-tag z) 'rectangular))

      (define (polar? z)
	(eq? (type-tag z) 'polar))


      (define (real-part z) (apply-generic 'real-part z))
      (define (imag-part z) (apply-generic 'imag-part z))
      (define (magnitude z) (apply-generic 'magnitude z))
      (define (angle z) (apply-generic 'angle z))

      (define (add x y) (apply-generic 'add x y))
      (define (sub x y) (apply-generic 'sub x y))
      (define (mul x y) (apply-generic 'mul x y))
      (define (div x y) (apply-generic 'div x y))

      (define (equ? x y)
	(apply-generic 'equ? x y))
      (define (zero? x) (apply-generic 'zero? x))

      (define (exp x y) (apply-generic 'exp x y))

      (define (install-scheme-number-package)
	(define (tag x)
	  (attach-tag 'scheme-number x))
	(put 'add '(scheme-number scheme-number)
	     (lambda (x y) (tag (+ x y))))
	(put 'sub '(scheme-number scheme-number)
	     (lambda (x y) (tag (- x y))))
	(put 'mul '(scheme-number scheme-number)
	     (lambda (x y) (tag (* x y))))
	(put 'div '(scheme-number scheme-number)
	     (lambda (x y) (tag (/ x y))))
	(put 'make 'scheme-number
	     (lambda (x) (tag x)))
	(put 'equ? '(scheme-number scheme-number)
	     (lambda (x y) (= x y)))
	(put 'zero? '(scheme-number)
	     (lambda (x) (= 0 x)))
	(put 'exp '(scheme-number scheme-number)
	     (lambda (x y) (tag (expt x y))))
	(put 'project '(scheme-number)
	     (lambda (x)
	       (exact (truncate x))))
	(put 'sine '(scheme-number) sin)
	(put 'cosine '(scheme-number) cos)
	(put 'square-root '(scheme-number) sqrt)
	(put 'arctangent '(schemer-number) atan)
	'done)

      (define (sine x) (apply-generic 'sine x))
      (define (cosine x) (apply-generic 'cosine x))
      (define (square-root x) (apply-generic 'square-root x))
      (define (arctangent x) (apply-generic 'arctangent x))

      (define (make-scheme-number n)
	((get 'make 'scheme-number) n))

      (define (install-rational-package)
	(define (numer x) (car x))
	(define (denom x) (cdr x))
	(define (make-rat n d)
	  #;(let ((g (gcd n d)))
	    (cons (/ n g) (/ d g)))
	    (cons n d))
	(define (add-rat x y)
	  (make-rat (add (mul (numer x) (denom y))
		       (mul (numer y) (denom x)))
		    (mul (denom x) (denom y))))
	(define (sub-rat x y)
	  (make-rat (sub (mul (numer x) (denom y))
		       (mul (numer y) (denom x)))
		    (mul (denom x) (denom y))))
	(define (mul-rat x y)
	  (make-rat (mul (numer x) (numer y))
		    (mul (denom x) (denom y))))
	(define (div-rat x y)
	  (make-rat (mul (numer x) (denom y))
		    (mul (denom x) (numer y))))

	(define (tag x) (attach-tag 'rational x))
	(put 'add '(rational rational)
	     (lambda (x y) (tag (add-rat x y))))
	(put 'sub '(rational rational)
	     (lambda (x y) (tag (sub-rat x y))))
	(put 'mul '(rational rational)
	     (lambda (x y) (tag (mul-rat x y))))
	(put 'div '(rational rational)
	     (lambda (x y) (tag (div-rat x y))))

	(put 'make 'rational
	     (lambda (n d) (tag (make-rat n d))))
	(put 'equ? '(rational rational)
	     (lambda (x y) (zero? (numer (sub-rat x y)))))
	(put 'zero? '(rational) (lambda (x) (zero? (numer x))))
	#;(put 'project '(rational) (lambda (x) 
				    (exact (truncate (/ (numer x) (denom x))))))
	#;(put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
	'done)

      (define (make-rational n d)
	((get 'make 'rational) n d))

      (define (install-rectangular-package)

	(define (real-part z) (car z))
	(define (imag-part z) (cdr z))
	(define (make-from-real-imag x y) (cons x y))
	(define (magnitude z)
	  (square-root (add (square (real-part z))
			    (square (imag-part z)))))
	(define (angle z)
	  (arctangent (imag-part z) (real-part z)))
	(define (make-from-mag-ang r a)
	  (cons (mul r (cosine a)) (mul r (sine a))))

	(define (tag x) (attach-tag 'rectangular x))
	(put 'real-part '(rectangular) real-part)
	(put 'imag-part '(rectangular) imag-part)
	(put 'magnitude '(rectangular) magnitude)
	(put 'angle '(rectangular) angle)
	(put 'make-from-real-imag 'rectangular
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'rectangular
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	'done)

      (define (install-polar-package)

	(define (magnitude z) (car z))
	(define (angle z) (cdr z))
	(define (make-from-mag-ang r a) (cons r a))
	(define (real-part z)
	  (mul (magnitude z) (cosine (angle z))))
	(define (imag-part z)
	  (mul (magnitude z) (sine (angle z))))
	(define (make-from-real-imag x y)
	  (cons (square-root (add (square x) (square y)))
		(arctangent y x)))

	(define (tag x) (attach-tag 'polar x))
	(put 'real-part '(polar) real-part)
	(put 'imag-part '(polar) imag-part)
	(put 'magnitude '(polar) magnitude)
	(put 'angle '(polar) angle)
	(put 'make-from-real-imag 'polar
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'polar
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	'done)

      (define (install-complex-package)
	(define (make-from-real-imag x y)
	  ((get 'make-from-real-imag 'rectangular) x y))
	(define (make-from-mag-ang r a)
	  ((get 'make-from-mag-ang 'polar) r a))
	(define (add-complex z1 z2)
	  (make-from-real-imag (add (real-part z1) (real-part z2))
			       (add (imag-part z1) (imag-part z2))))
	(define (sub-complex z1 z2)
	  (make-from-real-imag (sub (real-part z1) (real-part z2))
			       (sub (imag-part z1) (imag-part z2))))
	(define (mul-complex z1 z2)
	  (make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			     (add (angle z1) (angle z2))))
	(define (div-complex z1 z2)
	  (make-from-mag-ang (div (magnitude z1) (magnitude z2))
			     (sub (angle z1) (angle z2))))
	(define (tag z) (attach-tag 'complex z))
	(put 'add '(complex complex)
	     (lambda (z1 z2) (tag (add-complex z1 z2))))
	(put 'sub '(complex complex)
	     (lambda (z1 z2) (tag (sub-complex z1 z2))))
	(put 'mul '(complex complex)
	     (lambda (z1 z2) (tag (mul-complex z1 z2))))
	(put 'div '(complex complex)
	     (lambda (z1 z2) (tag (div-complex z1 z2))))
	(put 'make-from-real-imag 'complex
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'complex
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	(put 'equ? '(complex complex)
	     (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
				(= 0 (imag-part (sub-complex x y))))))
	(put 'equ? '(rectangular polar) equ?)
	(put 'equ? '(polar rectangular) equ?)
	(put 'zero? '(complex)
	     (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
	(put 'project '(complex) (lambda (z) (real-part z)))
	'done)

      (define (make-complex-from-real-imag x y)
	((get 'make-from-real-imag 'complex) x y))

      (define (make-complex-from-mag-ang r a)
	((get 'make-from-mag-ang 'complex) r a))

      (install-rectangular-package)
      (install-polar-package)
      (install-rational-package)
      (install-scheme-number-package)
      (install-complex-package)

      (put 'real-part '(complex) real-part)
      (put 'imag-part '(complex) imag-part)
      (put 'magnitude '(complex) magnitude)
      (put 'angle '(complex) angle)

      (define (apply-generic op . args)
	#;(show #t "apply-generic:entry\n")
	#;(error "debug")
	(define (variable poly) (car poly))
	(define (all-argtypes-same? . args)
	  (let ((type (type-tag (car args))))
	    (accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
	(define (coercion-if-exists? type arg-tags)
	  (let ((coercion-list (map (lambda (x) 
				      (if (eq? type x)
					  identity
					  (get-coercion x type))) arg-tags)))
	    (if (accumulate (lambda (x y) (and x y)) #t coercion-list)
		coercion-list
		#f)))
	(drop (let* ((type-tags (map type-tag args))
		     (proc (get op type-tags)))
		#;(show #t "apply-generic: type-tags=" 
			 (displayed type-tags)
			 " proc=" (written proc)
			 " proc-source=" (thingy-source proc) "\n")
		(cond (proc (apply proc (map contents args)))
		      ((= 1 (length args))
		       #;(show #t "No proc found for op=" op ", type-tags=" type-tags ", arg=" (displayed args) "\n")
		       (apply-generic op (raise-type (car args))))
		      ((= 2 (length args))
		       (cond ((and (eq? 'polynomial (car type-tags))
				 (numeric? (cadr type-tags)))
			      (apply-generic op
					     (car args)
					     (make-polynomial (variable (contents (car args)))
							      (list (list 0 (cadr args))))))
			     ((and (numeric? (car type-tags))
				 (eq? 'polynomial (cadr type-tags)))
			      (apply-generic op
					     (make-polynomial (variable (contents (cadr args)))
							      (list (list 0 (car args))))
					     (cadr args)))			 
			     ((and (get-coercion (car type-tags) (cadr type-tags))
				 (not (eq? (car type-tags) (cadr type-tags))))
			      (apply-generic op
					     ((get-coercion
					       (car type-tags)
					       (cadr type-tags)) (car args))
					     (cadr args)))
			     ((and (get-coercion (cadr type-tags) (car type-tags))
				 (not (eq? (car type-tags) (cadr type-tags))))
			      (apply-generic op
					     (car args)
					     ((get-coercion
					       (cadr type-tags)
					       (car type-tags)) (cadr args) )))
			     ((comparable? (car type-tags) (cadr type-tags))
			      (if
			       (type1<=type2? (car type-tags) (cadr type-tags))
			       (apply-generic op (raise-type (car args)) (cadr args))
			       (apply-generic op (car args)  (raise-type (cadr args)))))
			     (else (error "apply-generic:Incomparable types: (type-tags,args)=" type-tags args))))
		      ((and (> (length args) 2) (not (all-argtypes-same? args)))
		       (let types-loop ((types type-tags))
			 (let ((list-of-coercion-functions
				(coercion-if-exists? (car types) type-tags)))
			   (if list-of-coercion-functions
			       (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
								  list-of-coercion-functions
								  args)))
			       (if (not (null? (cdr types)))
				   (types-loop (cdr types))
				   (error "apply-generic:Even coercions failed. No method for these types."))))))
		      (else (error "apply-generic:No method for these types"
				   (list op type-tags)))))))
      (define (scheme-number->complex n)
	(make-complex-from-real-imag (contents n) 0))
      (put-coercion 'scheme-number
		    'complex
		    scheme-number->complex)

      (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
							(max (magnitude z1) (magnitude z2) (magnitude z3))))
      (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
      (define (identity x) x)

    #;(define numeric-tower (list 'integer 'rational 'scheme-number 'complex))
    (define numeric-tower (list 'integer 'scheme-number 'complex))
    (define (comparable? type1 type2) (and (memq type1 numeric-tower) (memq type2 numeric-tower)))
    #;(define (higher-type x)
      (show #t "higher-type:x=" (displayed x) "\n")
	(define (find-higher-type x types)
	  (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x types))
		((eq? x (car types)) (cadr types))
		(else (find-higher-type x (cdr types)))))
	(find-higher-type x numeric-tower))

    (define (numeric? x)
      (memq x numeric-tower))
    (define (polynomial? x)
      (eq? (type-tag x) 'polynomial))
    (define (higher-type x)
      (let ((tail (memq x numeric-tower)))
	(cond ((eq? #f tail) (error "Type not in the tower" x))
	      ((null? (cdr tail)) (error "Already the highest type:" x))
	      (else (cadr tail)))))

    (show #t "Test: Higher than 'integer: " (higher-type 'integer) "\n")
    #;(show #t "Test: Higher than 'complex: " (higher-type 'complex) "\n")

      (define (type1<=type2? type1 type2)
	(if (not (memq type1 numeric-tower))
	    (error "Type 1 not in the numeric tower"))
	(if (not (memq type2 numeric-tower))
	    (error "Type 2 not in the numeric tower"))
	(let loop ((types numeric-tower))
	  (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
		((eq? (car types) type1) #t)
		((eq? (car types) type2) #f)
		(else (loop (cdr types))))))

      #;(define (integer->rational x)
	(make-rational x 1))

      #;(define (rational->scheme-number x)
	(make-scheme-number ((get 'to-real '(rational)) x)))
      #;(put-coercion 'integer 'rational integer->rational)
      #;(put-coercion 'rational 'scheme-number rational->scheme-number)
    (define (integer->scheme-number x)
       (make-scheme-number (contents (exact->inexact x))))
    (put-coercion 'integer 'scheme-number integer->scheme-number)  

    (define (raise-type x)
      #;(show #t "Raising type of: " (displayed x) "\n")
	(let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
	  (if converter
	      (converter x)
	      (error "No coercion found for x" (type-tag x) x))))


      (define (remainder-integer a b)
	(when (or (not (integer? a)) (not (integer? b)))
	  (error "Arguments must be integers" a b))
	(remainder a b))

      (put 'remainder '(integer integer) remainder-integer)
      (define (remainder-generalized a b) (apply-generic 'remainder a b))

      (define (project obj)
	(apply-generic 'project obj))
      (define (droppable? obj)
	#;(show #t "droppable?: obj=" obj ", type-tag=" (type-tag obj) "\n")
	(cond ((eq? (type-tag obj) 'rational) (begin (show #t "rational not droppable: #f\n") #f))
	      ((not (memq (type-tag obj) numeric-tower)) #f)
	      ((eq? (type-tag obj) (car numeric-tower)) #f)
	      ((equ? obj (raise-type (project obj))) #t)
	      (else #f)))
      (define (drop obj) 
	(if (droppable? obj)
	    (drop (project obj))
	    obj))

      (show #t "Test 1: Subtracting complex numbers: "
	    (sub
	     (make-complex-from-real-imag 1.1 2)
	     (make-complex-from-real-imag 0 2)) "\n")
    (define (install-polynomial-package)
      #;(define (contents generic-object)
	(cdr generic-object))
	(define (make-poly variable term-list)
	  (cons variable term-list))
	(define (variable p) (car p))
	(define (term-list p)
	  (cdr p))
	(define (variable? x) (symbol? x))
	(define (same-variable? v1 v2)
	  (and (variable? v1) (variable? v2) (eq? v1 v2)))
	(define (=number? exp num)
	  (and (number? exp) (= exp num)))
	(define (the-empty-termlist) '())

	(define (rest-terms term-list) (cdr term-list))
	(define (empty-termlist? term-list) (null? term-list))

	(define (make-term order coeff) (list order coeff))
	(define (order term) (car term))
	(define (coeff term) (cadr term))
	(define (tag p) (attach-tag 'polynomial p))
	(put 'make 'polynomial
	     (lambda (var terms) (tag (make-poly var terms))))
	#;(continued on next page)

	(define (add-poly p1 p2)
	  #;(show #t "add-poly: p1=" p1 ", p2=" p2 "\n")
	  (if (same-variable? (variable p1) (variable p2))
	      (make-poly (variable p1)
			 (add-terms (term-list p1)
				    (term-list p2)))
	      (let ((res (cdr (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		  (add (tag p1) (tag (make-poly (variable p1) (list (make-term 0 (tag p2))))))
		  (add (tag (make-poly (variable p2) (list (make-term 0 (tag p1))))) (tag p2))))))
		#;(show #t "add-poly:result: " (displayed res) "\n") res)))

	(show #t "TestY2: poly of poly: "
	      (make-poly 'x (list
			     (make-term 3 (make-poly
					   'y (list (make-term 1 1) (make-term 0 1))))
			     (make-term 1 2)
			     (make-term 0 4))) "\n")

	(define (sub-poly p1 p2)
	  (add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
	(define (add-terms L1 L2)
	  (cond ((empty-termlist? L1) L2)
		((empty-termlist? L2) L1)
		(else
		 (let ((t1 (first-term L1)) (t2 (first-term L2)))
		   (cond ((> (order t1) (order t2))
			  (adjoin-term
			   t1 (add-terms (rest-terms L1) L2)))
			 ((< (order t1) (order t2))
			  (adjoin-term
			   t2 (add-terms L1 (rest-terms L2))))
			 (else
			  (adjoin-term
			   (make-term (order t1)
				      (add (coeff t1) (coeff t2)))
			   (add-terms (rest-terms L1)
				      (rest-terms L2)))))))))


	(define (mul-poly p1 p2)
	  (if (same-variable? (variable p1) (variable p2))
	      (make-poly (variable p1)
			 (mul-terms (term-list p1)
				    (term-list p2)))
	      (contents (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		  (mul (tag p1)
		       (make-polynomial (variable p1)
					(adjoin-term
					 (make-term 0
						    (tag p2)) (the-empty-termlist))))
		  (mul (tag p2)
		       (make-polynomial (variable p2)
					(adjoin-term
					 (make-term 0
						    (tag p1)) (the-empty-termlist))))))
	      #;(error "Polys not in same var -- MUL-POLY"
		     (list p1 p2))))
	(define (div-poly p1 p2)
	  (if (same-variable? (variable p1) (variable p2))
	      (let ((quotient-and-remainder (div-terms (term-list p1)
						       (term-list p2))))
		(list (make-poly (variable p1) (car  quotient-and-remainder))
		      (make-poly (variable p1) (cadr quotient-and-remainder))))
		(error "div-poly: Polys not in the same var" p1 p2)))
	(define (div-terms L1 L2)
		(if (empty-termlist? L1)
		    (list (the-empty-termlist) (the-empty-termlist))
		    (let ((t1 (first-term L1))
			  (t2 (first-term L2)))
		      (if (> (order t2) (order t1))
			  (list (the-empty-termlist) L1)
			  (let ((new-c (div (coeff t1) (coeff t2)))
				(new-o (- (order t1) (order t2))))
			    (let ((rest-of-result (div-terms (term-list
							      (sub-poly
							       (make-poly 'fake-var L1)
							       (mul-poly
								(make-poly 'fake-var (list (make-term new-o new-c)))
								(make-poly 'fake-var L2))))
							     L2)
						  ))
			      #;(show #t "div-terms: rest-of-result: " (displayed rest-of-result) "\n")
			      (list (adjoin-term (make-term new-o new-c) (car rest-of-result)) (cadr rest-of-result))
			      ))))))
	(define (mul-terms L1 L2)
	  (if (empty-termlist? L1)
	      (the-empty-termlist)
	      (add-terms (mul-term-by-all-terms (first-term L1) L2)
			 (mul-terms (rest-terms L1) L2))))

	(define (mul-term-by-all-terms t1 L)
	  (if (empty-termlist? L)
	      (the-empty-termlist)
	      (let ((t2 (first-term L)))
		(adjoin-term
		 (make-term (+ (order t1) (order t2))
			    (mul (coeff t1) (coeff t2)))
		 (mul-term-by-all-terms t1 (rest-terms L))))))
	(define (zero-poly? poly)
	  #;(show #t "zero-poly?: poly=" (displayed poly) "\n")
	  (cond ((empty-termlist? (term-list poly)) #t)
		((not (zero? (coeff (first-term (term-list poly))))) #f)
		(else (zero-poly? 
		       (make-poly (variable poly)
				  (rest-terms (term-list poly)))))))

	(define (termlist-type-of term-list)
	  #;(show #t "t-t-o: term-list=" (displayed term-list) "\n")
	  (cond ((null? term-list) 'sparse)
		((pair? (car term-list)) 'sparse)
		((list? term-list) 'dense)
		(else (error "Unknown type of list" term-list))))
	(define (adjoin-term term term-list)
	  ((get 'adjoin-term (termlist-type-of term-list)) term term-list))
	(define (first-term term-list)
	  ((get 'first-term (termlist-type-of term-list)) term-list))
	(define (variable_1-order<variable_2-order variable_1 variable_2)
	  #;(show #t "var_1-..: variable_1=" variable_1 " variable_2=" variable_2 "\n")
	  #;(show #t "var12string=" (symbol->string variable_1) "var22string=" (symbol->string variable_2) "\n")
	  (string<=? (symbol->string variable_1) (symbol->string variable_2)))
	(define (normalize-fully poly)
	  (if (normal-polynomial? poly)
	      poly
	      (normalize-fully (normalize-once poly))))
	(put 'add '(polynomial polynomial)
	     (lambda (p1 p2) 
	       #;(show #t "generic-add-poly:Polynomial dispatch found: p1="
		      (displayed p1) " p2=" (displayed p2) "\n")
	       (normalize-fully (tag (add-poly p1 p2)))))
	(put 'mul '(polynomial polynomial)
	     (lambda (p1 p2) (normalize-fully (tag (mul-poly p1 p2)))))
	(put 'sub '(polynomial polynomial)
	     (lambda (p1 p2) (tag (sub-poly p1 p2))))

	(put 'zero? '(polynomial) zero-poly?)
	(put 'div '(polynomial polynomial) div-poly)
	#;(put-coercion 'rational 'scheme-number rational->scheme-number)
	(define (monomial-flip-variables monomial)
	  #;(show #t "m-f-v: monomial=" monomial "\n")
	  (let* ((mono (contents monomial))
		 (inner-polynomial (contents (coeff (first-term (term-list mono)))))
		 (inner-poly (contents inner-polynomial))
		 (outer-order (order (first-term (term-list mono))))
		 (outer-var (variable mono))
		 (inner-var (variable inner-polynomial))
		 (inner-term-list (term-list inner-poly)))
	    #;(show #t "m-f-v: inner-poly=" inner-poly "\n")
	    (if (same-variable? inner-var outer-var)
		(mul
		 (make-polynomial outer-var (adjoin-term (make-term outer-order 1) (the-empty-termlist)))
		 (tag inner-polynomial))
		(tag (make-poly inner-var
				(mul-term-by-all-terms (make-term
							0
							(make-polynomial
							 outer-var
							 (list (make-term
								outer-order
								1)))) inner-poly))))))
	#;(show #t "TestXX: sorting variables: Is 'x < 'y?: "
	      (variable_1-order<variable_2-order 'x 'y) "\n")
	#;(show #t "TestXX: sorting variables: Is 'z < 'y?: "
	      (variable_1-order<variable_2-order 'z 'y) "\n")
	#;(show #t "TestXX: (adding two basic poly): "
	      (add (make-polynomial 'x (list (make-term 1 2) (make-term 0 4)))
		   (make-polynomial 'y (list (make-term 2 3) (make-term 0 5)))) "\n")

	(define (polynomial->sum-of-first-and-rest poly)
	  #;(show #t "p->s-o-f-a-r: " (displayed poly) "\n")
	  (if (zero? poly)
	      poly
	      (let* ((poly1 (contents poly))
		     (first-monomial (tag
				      (make-poly
				       (variable poly1)
				       (list (first-term (term-list poly1)))))))
		#;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		(add
		  first-monomial
		  (polynomial->sum-of-first-and-rest
		   (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	(show #t "Test13: Expanding a polynomial as monomials: "
	      (displayed
	       (polynomial->sum-of-first-and-rest
		(make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))))) "\n")

	(show #t "\nTest20: start monomial: "
	      (displayed (make-polynomial 'x
					  (list
					   (make-term
					    2
					    (make-polynomial
					     'y
					     (list
					      (make-term 2 1) (make-term 0 1))))))) "\n")
	(show #t "Test20: Flipping a monomial variable: "
	      (displayed
	       (monomial-flip-variables
		(make-polynomial 'x
				 (list (make-term 1 (make-polynomial
						     'y
						     (list
						      (make-term 2 1)
						      (make-term 0 1)))))))) "\n\n")


	(define (normal-polynomial? poly)
	  #;(show #t "n-p?: poly=" poly "\n")
	  (cond ((not (polynomial? poly)) #t)
		((null? (term-list (contents poly))) #t)
		(else (let* ((poly1 (contents poly))
			     (outer-var (variable poly1)))
			#;(show #t "Inner-let: outer-var=" (displayed outer-var) "\n")
			(let loop ((terms (term-list poly1)))
			  #;(show #t "n-p?-loop: terms=" (displayed terms) "\n")
			  (cond ((null? terms) #t)
				((not (polynomial? (coeff (first-term terms)))) (loop (rest-terms terms)))
				((not (variable_1-order<variable_2-order 
				     outer-var
				     (variable (contents (coeff (first-term terms)))))) (begin #;(show #t "wrong variable order \n") #f))
				((not (normal-polynomial? (coeff (first-term terms)))) (begin #;(show #t "not normal poly\n") #f))
				(else (loop (rest-terms terms)))))
			))))
	(define (normalize-once poly)
	  #;(show #t "normalize-once poly= " (displayed poly) "\n")
	  (if (zero? poly)
	      poly
	      (let* ((poly1 (contents poly))
		     (first-monomial (tag
				      (make-poly
				       (variable poly1)
				       (list (make-term
					      (order (first-term (term-list poly1)))
					      (if (polynomial? (coeff (first-term (term-list poly1))))
						  (normalize-once (coeff (first-term (term-list poly1))))
						  (coeff (first-term (term-list poly1))))))))))
		#;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		(add
		 (if (and (polynomial?
			 (coeff
			  (first-term
			   (term-list
			    (contents first-monomial)))))
			(variable_1-order<variable_2-order
			 (variable
			  (contents
			   (coeff
			    (first-term
			     (term-list
			      (contents first-monomial))))))
			 (variable
			  (contents first-monomial))))
		     (monomial-flip-variables first-monomial)
		     first-monomial)
		  (polynomial->sum-of-first-and-rest
		   (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	(show #t "Test21: normal-polynomial?:start: " (displayed (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test21: normal-polynomial?:result:" (normal-polynomial? (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test22: normal-polynomial?-good:start: "
	      (displayed
	       (make-polynomial 'x
				(list (make-term 2 (make-polynomial
						    'y
						    (list (make-term 2 1) (make-term 0 1))))
				      (make-term 0 2)))) "\n")
	(show #t "Test22: normal-polynomial?-good:result:"
	      (normal-polynomial?
	       (make-polynomial 'x
				(list (make-term 2 (make-polynomial
						    'y
						    (list (make-term 2 1) (make-term 0 1))))
				      (make-term 0 2)))) "\n")

	(show #t "Test23:input: normalizing a bad polynomial: "
	      (make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test23:result: normalizing a bad polynomial: "
	      (normalize-once (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test24:input: normalizing a bad polynomial: "
	      (make-polynomial 'x
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test24:result: normalizing a bad polynomial: "
	      (normalize-once (make-polynomial 'x
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")


	(show #t "Test24:input: normalize-fully a bad polynomial: "
	      (make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test24:result: normalize-fully a bad polynomial: "
	      (normalize-fully (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")



	'done)


      (define (install-polynomial-sparse-package)
	(define (coeff term) (cadr term))
	(define (first-term-sparse term-list) (car term-list))
	(define (adjoin-term-sparse term term-list)
	  (if (zero? (coeff term))
	      term-list
	      (cons term term-list)))
	(put 'adjoin-term 'sparse adjoin-term-sparse)
	(put 'first-term 'sparse first-term-sparse)
	'done)
      (install-polynomial-sparse-package)

      (define (install-polynomial-dense-package)
	(define (make-term order coeff) (list order coeff))
	(define (order term) (car term))
	(define (coeff term) (cadr term))

	(define (adjoin-term-dense term term-list)
	    (if (zero? (coeff term))
		term-list
		(if (> (order term) (length term-list))
		    (append (list (coeff term))
			    (make-list (- (order term) (length term-list)) 0)
			    term-list)
		    (error "adjoin-term:Appending a smaller order term. Recheck."))))
	(define (first-term-dense term-list) 
	   #;(show #t "first-term-dense: " (displayed (make-term (car term-list) (length (cdr term-list)))) "\n")
	   (make-term (length (cdr term-list)) (car term-list) ))
	(put 'adjoin-term 'dense adjoin-term-dense)
	(put 'first-term 'dense first-term-dense)
	'done)
      #;(install-polynomial-dense-package)

      (define (make-polynomial var terms)
	((get 'make 'polynomial) var terms))

    (install-polynomial-package)


      #;(show #t "Test 2: Making polynomials: " 
	    (make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
      #;(show #t "Test 3: Zero?: " 
	    (zero? (make-polynomial 'x (list (list 5 1) (list 4 2)))) "\n")
      #;(show #t "Test 4: Adding polynomials: "
	    (add (make-polynomial 'x '((5 1) (4 2) (0 1)))
		 (make-polynomial 'x '((5 1)))) "\n")
      #;(show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

      #;(show #t "Test 5: Subtracting polynomials: "
	    (sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
		 (make-polynomial 'x '((0 1)))) "\n")

      #;(show #t "Test 6: Making a dense polynomial: " (make-polynomial 'x '(1 2 3 4 5)) "\n")
      #;(show #t "Test 7: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(0)))) "\n")
      #;(show #t "Test 8: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(1)))) "\n")
      #;(show #t "Test 9: Adding dense polynomials: "
	    (add (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
      #;(show #t "Test10: Subtracting dense polynomials: "
	    (sub (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
      #;(show #t "Test11: Subtracting dense and sparse polynomials: "
	    (sub (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '((4 2)))) "\n")
      #;(show #t "Test12: Dividing x^2 + 2x + 1 by x+1: "
	    (displayed
	     (div (make-polynomial 'x '((2 1) (1 2) (0 1)))
		  (make-polynomial 'x '(      (1 1) (0 1)))) ) "\n")
      #;(show #t "Test14: Adding polynomials of two variables: "
	    (displayed
	     (add (make-polynomial 'x '((1 1)))
		  (make-polynomial 'y '((1 1))))))
      #;(show #t "Test14: Adding polynomials of two variables, when one of them is nonexistant: "
	    (displayed
	     (add (make-polynomial 'x '((1 1)))
		  (make-polynomial 'y '((0 1))))))
    (show #t "Test25: multiplying different variables: "
	  (displayed (mul (make-polynomial 'x '((1 1)))
			  (make-polynomial 'y '((1 1))))) "\n")

  (define p1 (make-polynomial 'x '((2 1) (0 1))))
  (define p2 (make-polynomial 'x '((3 1) (0 1))))
  (define rf (make-rational p2 p1))
  (show #t "Test 26: make-rational-polynomial: " rf "\n")
  (show #t "Test 27: add-rational\n")
  (show #t "Test 27: " (add rf rf) "\n")
#+end_src

#+RESULTS:
#+begin_example
Test: Higher than 'integer: scheme-number
Test 1: Subtracting complex numbers: (scheme-number . 1.1)
TestY2: poly of poly: (x (3 (y (1 1) (0 1))) (1 2) (0 4))
Test13: Expanding a polynomial as monomials: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))

Test20: start monomial: (polynomial x (2 (polynomial y (2 1) (0 1))))
Test20: Flipping a monomial variable: (polynomial y (2 (polynomial x (1 1))) (0 (polynomial x (1 1))))

Test21: normal-polynomial?:start: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test21: normal-polynomial?:result:#f
Test22: normal-polynomial?-good:start: (polynomial x (2 (polynomial y (2 1) (0 1))) (0 2))
Test22: normal-polynomial?-good:result:#t
Test23:input: normalizing a bad polynomial: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test23:result: normalizing a bad polynomial: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))
Test24:input: normalizing a bad polynomial: (polynomial x (2 (polynomial x (2 1) (0 1))) (0 2))
Test24:result: normalizing a bad polynomial: (polynomial x (4 1) (2 1) (0 2))
Test24:input: normalize-fully a bad polynomial: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test24:result: normalize-fully a bad polynomial: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))
Test25: multiplying different variables: (polynomial x (1 (polynomial y (1 1))))
Test 26: make-rational-polynomial: (rational (polynomial x (3 1) (0 1)) polynomial x (2 1) (0 1))
Test 27: add-rational
rational not droppable: #f
Test 27: (rational (polynomial x (5 2) (3 2) (2 2) (0 2)) polynomial x (4 1) (2 2) (0 1))
#+end_example

*** DONE Exercise 2.94 Greatest-common-divisor for polynomials
    CLOSED: [2019-10-28 Mon 00:47]

I will still copy the source code of the whole Computer Algebra System,
because extending the system with a GCD subroutine would require adding
functions to the polynomial package, which cannot be done with a mere
include.

#+begin_src scheme :exports both :results output :noweb-ref cas-with-rational-polynomials
    (define (thingy-source thingy)
      (cond ((lambda? thingy) (list "lambda" (lambda-source thingy)))
	    ((procedure? thingy) (list "procedure" (procedure-name thingy)))
	    ((pair? thingy) (list "pair" (pair-source thingy)))
	    (else "No source? refactor")))

      (define (accumulate op initial sequence)
	(if (null? sequence)
	    initial
	    (accumulate op (op initial (car sequence)) (cdr sequence))))
      (define false #f)
      (define true  #t)
      (define (make-table)
	(let ((local-table (list '*table*)))
	  (define (lookup key-1 key-2)
	    (let ((subtable (assoc key-1 (cdr local-table))))
	      (if subtable
		  (let ((record (assoc key-2 (cdr subtable))))
		    (if record
			(cdr record)
			false))
		  false)))
	  (define (insert! key-1 key-2 value)
	    (let ((subtable (assoc key-1 (cdr local-table))))
	      (if subtable
		  (let ((record (assoc key-2 (cdr subtable))))
		    (if record
			(set-cdr! record value)
			(set-cdr! subtable
				  (cons (cons key-2 value)
					(cdr subtable)))))
		  (set-cdr! local-table
			    (cons (list key-1
					(cons key-2 value))
				  (cdr local-table)))))
	    'ok)
	  (define (dispatch m)
	    (cond ((eq? m 'lookup-proc) lookup)
		  ((eq? m 'insert-proc!) insert!)
		  (else (error "Unknown operation -- TABLE" m))))
	  dispatch))

      (define operation-table (make-table))
      (define get (operation-table 'lookup-proc))
      (define put (operation-table 'insert-proc!))

      (define coercion-table (make-table))
      (define get-coercion (coercion-table 'lookup-proc))
      (define put-coercion (coercion-table 'insert-proc!))

      (define (attach-tag type-tag contents)
	(cons type-tag contents))

      (define (type-tag datum)
	(cond ((pair? datum) (car datum))
	      ((exact-integer? datum) 'integer)
	      ((real? datum) 'scheme-number)
	      (error "Bad tagged datum -- TYPE-TAG" datum)))

    (define (contents datum)
	(cond ((pair? datum) (cdr datum))
	      ((integer? datum) datum)
	      ((real? datum) datum)
	      (else (error "Bad tagged datum -- CONTENTS" datum))))

      (define (integer? x)
	(eq? (type-tag x) 'integer))
      (define (rectangular? z)
	(eq? (type-tag z) 'rectangular))

      (define (polar? z)
	(eq? (type-tag z) 'polar))


      (define (real-part z) (apply-generic 'real-part z))
      (define (imag-part z) (apply-generic 'imag-part z))
      (define (magnitude z) (apply-generic 'magnitude z))
      (define (angle z) (apply-generic 'angle z))

      (define (add x y) (apply-generic 'add x y))
      (define (sub x y) (apply-generic 'sub x y))
      (define (mul x y) (apply-generic 'mul x y))
      (define (div x y) (apply-generic 'div x y))

      (define (equ? x y)
	(apply-generic 'equ? x y))
      (define (zero? x) (apply-generic 'zero? x))

      (define (exp x y) (apply-generic 'exp x y))

      (define (install-scheme-number-package)
	(define (tag x)
	  (attach-tag 'scheme-number x))
	(put 'add '(scheme-number scheme-number)
	     (lambda (x y) (tag (+ x y))))
	(put 'sub '(scheme-number scheme-number)
	     (lambda (x y) (tag (- x y))))
	(put 'mul '(scheme-number scheme-number)
	     (lambda (x y) (tag (* x y))))
	(put 'div '(scheme-number scheme-number)
	     (lambda (x y) (tag (/ x y))))
	(put 'make 'scheme-number
	     (lambda (x) (tag x)))
	(put 'equ? '(scheme-number scheme-number)
	     (lambda (x y) (= x y)))
	(put 'zero? '(scheme-number)
	     (lambda (x) (= 0 x)))
	(put 'exp '(scheme-number scheme-number)
	     (lambda (x y) (tag (expt x y))))
	(put 'project '(scheme-number)
	     (lambda (x)
	       (exact (truncate x))))
	(put 'sine '(scheme-number) sin)
	(put 'cosine '(scheme-number) cos)
	(put 'square-root '(scheme-number) sqrt)
	(put 'arctangent '(schemer-number) atan)
	'done)

      (define (sine x) (apply-generic 'sine x))
      (define (cosine x) (apply-generic 'cosine x))
      (define (square-root x) (apply-generic 'square-root x))
      (define (arctangent x) (apply-generic 'arctangent x))

      (define (make-scheme-number n)
	((get 'make 'scheme-number) n))

      (define (install-rational-package)
	(define (numer x) (car x))
	(define (denom x) (cdr x))
	(define (make-rat n d)
	  #;(let ((g (gcd n d)))
	    (cons (/ n g) (/ d g)))
	    (cons n d))
	(define (add-rat x y)
	  (make-rat (add (mul (numer x) (denom y))
		       (mul (numer y) (denom x)))
		    (mul (denom x) (denom y))))
	(define (sub-rat x y)
	  (make-rat (sub (mul (numer x) (denom y))
		       (mul (numer y) (denom x)))
		    (mul (denom x) (denom y))))
	(define (mul-rat x y)
	  (make-rat (mul (numer x) (numer y))
		    (mul (denom x) (denom y))))
	(define (div-rat x y)
	  (make-rat (mul (numer x) (denom y))
		    (mul (denom x) (numer y))))

	(define (tag x) (attach-tag 'rational x))
	(put 'add '(rational rational)
	     (lambda (x y) (tag (add-rat x y))))
	(put 'sub '(rational rational)
	     (lambda (x y) (tag (sub-rat x y))))
	(put 'mul '(rational rational)
	     (lambda (x y) (tag (mul-rat x y))))
	(put 'div '(rational rational)
	     (lambda (x y) (tag (div-rat x y))))

	(put 'make 'rational
	     (lambda (n d) (tag (make-rat n d))))
	(put 'equ? '(rational rational)
	     (lambda (x y) (zero? (numer (sub-rat x y)))))
	(put 'zero? '(rational) (lambda (x) (zero? (numer x))))
	#;(put 'project '(rational) (lambda (x) 
				    (exact (truncate (/ (numer x) (denom x))))))
	#;(put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
	'done)

      (define (make-rational n d)
	((get 'make 'rational) n d))

      (define (install-rectangular-package)

	(define (real-part z) (car z))
	(define (imag-part z) (cdr z))
	(define (make-from-real-imag x y) (cons x y))
	(define (magnitude z)
	  (square-root (add (square (real-part z))
			    (square (imag-part z)))))
	(define (angle z)
	  (arctangent (imag-part z) (real-part z)))
	(define (make-from-mag-ang r a)
	  (cons (mul r (cosine a)) (mul r (sine a))))

	(define (tag x) (attach-tag 'rectangular x))
	(put 'real-part '(rectangular) real-part)
	(put 'imag-part '(rectangular) imag-part)
	(put 'magnitude '(rectangular) magnitude)
	(put 'angle '(rectangular) angle)
	(put 'make-from-real-imag 'rectangular
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'rectangular
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	'done)

      (define (install-polar-package)

	(define (magnitude z) (car z))
	(define (angle z) (cdr z))
	(define (make-from-mag-ang r a) (cons r a))
	(define (real-part z)
	  (mul (magnitude z) (cosine (angle z))))
	(define (imag-part z)
	  (mul (magnitude z) (sine (angle z))))
	(define (make-from-real-imag x y)
	  (cons (square-root (add (square x) (square y)))
		(arctangent y x)))

	(define (tag x) (attach-tag 'polar x))
	(put 'real-part '(polar) real-part)
	(put 'imag-part '(polar) imag-part)
	(put 'magnitude '(polar) magnitude)
	(put 'angle '(polar) angle)
	(put 'make-from-real-imag 'polar
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'polar
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	'done)

      (define (install-complex-package)
	(define (make-from-real-imag x y)
	  ((get 'make-from-real-imag 'rectangular) x y))
	(define (make-from-mag-ang r a)
	  ((get 'make-from-mag-ang 'polar) r a))
	(define (add-complex z1 z2)
	  (make-from-real-imag (add (real-part z1) (real-part z2))
			       (add (imag-part z1) (imag-part z2))))
	(define (sub-complex z1 z2)
	  (make-from-real-imag (sub (real-part z1) (real-part z2))
			       (sub (imag-part z1) (imag-part z2))))
	(define (mul-complex z1 z2)
	  (make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			     (add (angle z1) (angle z2))))
	(define (div-complex z1 z2)
	  (make-from-mag-ang (div (magnitude z1) (magnitude z2))
			     (sub (angle z1) (angle z2))))
	(define (tag z) (attach-tag 'complex z))
	(put 'add '(complex complex)
	     (lambda (z1 z2) (tag (add-complex z1 z2))))
	(put 'sub '(complex complex)
	     (lambda (z1 z2) (tag (sub-complex z1 z2))))
	(put 'mul '(complex complex)
	     (lambda (z1 z2) (tag (mul-complex z1 z2))))
	(put 'div '(complex complex)
	     (lambda (z1 z2) (tag (div-complex z1 z2))))
	(put 'make-from-real-imag 'complex
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'complex
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	(put 'equ? '(complex complex)
	     (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
				(= 0 (imag-part (sub-complex x y))))))
	(put 'equ? '(rectangular polar) equ?)
	(put 'equ? '(polar rectangular) equ?)
	(put 'zero? '(complex)
	     (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
	(put 'project '(complex) (lambda (z) (real-part z)))
	'done)

      (define (make-complex-from-real-imag x y)
	((get 'make-from-real-imag 'complex) x y))

      (define (make-complex-from-mag-ang r a)
	((get 'make-from-mag-ang 'complex) r a))

      (install-rectangular-package)
      (install-polar-package)
      (install-rational-package)
      (install-scheme-number-package)
      (install-complex-package)

      (put 'real-part '(complex) real-part)
      (put 'imag-part '(complex) imag-part)
      (put 'magnitude '(complex) magnitude)
      (put 'angle '(complex) angle)

      (define (apply-generic op . args)
	#;(show #t "apply-generic:entry\n")
	#;(error "debug")
	(define (variable poly) (car poly))
	(define (all-argtypes-same? . args)
	  (let ((type (type-tag (car args))))
	    (accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
	(define (coercion-if-exists? type arg-tags)
	  (let ((coercion-list (map (lambda (x) 
				      (if (eq? type x)
					  identity
					  (get-coercion x type))) arg-tags)))
	    (if (accumulate (lambda (x y) (and x y)) #t coercion-list)
		coercion-list
		#f)))
	(drop (let* ((type-tags (map type-tag args))
		     (proc (get op type-tags)))
		#;(show #t "apply-generic: type-tags=" 
			 (displayed type-tags)
			 " proc=" (written proc)
			 " proc-source=" (thingy-source proc) "\n")
		(cond (proc (apply proc (map contents args)))
		      ((= 1 (length args))
		       #;(show #t "No proc found for op=" op ", type-tags=" type-tags ", arg=" (displayed args) "\n")
		       (apply-generic op (raise-type (car args))))
		      ((= 2 (length args))
		       (cond ((and (eq? 'polynomial (car type-tags))
				 (numeric? (cadr type-tags)))
			      (apply-generic op
					     (car args)
					     (make-polynomial (variable (contents (car args)))
							      (list (list 0 (cadr args))))))
			     ((and (numeric? (car type-tags))
				 (eq? 'polynomial (cadr type-tags)))
			      (apply-generic op
					     (make-polynomial (variable (contents (cadr args)))
							      (list (list 0 (car args))))
					     (cadr args)))			 
			     ((and (get-coercion (car type-tags) (cadr type-tags))
				 (not (eq? (car type-tags) (cadr type-tags))))
			      (apply-generic op
					     ((get-coercion
					       (car type-tags)
					       (cadr type-tags)) (car args))
					     (cadr args)))
			     ((and (get-coercion (cadr type-tags) (car type-tags))
				 (not (eq? (car type-tags) (cadr type-tags))))
			      (apply-generic op
					     (car args)
					     ((get-coercion
					       (cadr type-tags)
					       (car type-tags)) (cadr args) )))
			     ((comparable? (car type-tags) (cadr type-tags))
			      (if
			       (type1<=type2? (car type-tags) (cadr type-tags))
			       (apply-generic op (raise-type (car args)) (cadr args))
			       (apply-generic op (car args)  (raise-type (cadr args)))))
			     (else (error "apply-generic:Incomparable types: (type-tags,args)=" type-tags args))))
		      ((and (> (length args) 2) (not (all-argtypes-same? args)))
		       (let types-loop ((types type-tags))
			 (let ((list-of-coercion-functions
				(coercion-if-exists? (car types) type-tags)))
			   (if list-of-coercion-functions
			       (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
								  list-of-coercion-functions
								  args)))
			       (if (not (null? (cdr types)))
				   (types-loop (cdr types))
				   (error "apply-generic:Even coercions failed. No method for these types."))))))
		      (else (error "apply-generic:No method for these types"
				   (list op type-tags)))))))
      (define (scheme-number->complex n)
	(make-complex-from-real-imag (contents n) 0))
      (put-coercion 'scheme-number
		    'complex
		    scheme-number->complex)

      (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
							(max (magnitude z1) (magnitude z2) (magnitude z3))))
      (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
      (define (identity x) x)

    #;(define numeric-tower (list 'integer 'rational 'scheme-number 'complex))
    (define numeric-tower (list 'integer 'scheme-number 'complex))
    (define (comparable? type1 type2) (and (memq type1 numeric-tower) (memq type2 numeric-tower)))
    #;(define (higher-type x)
      (show #t "higher-type:x=" (displayed x) "\n")
	(define (find-higher-type x types)
	  (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x types))
		((eq? x (car types)) (cadr types))
		(else (find-higher-type x (cdr types)))))
	(find-higher-type x numeric-tower))

    (define (numeric? x)
      (memq x numeric-tower))
    (define (polynomial? x)
      (eq? (type-tag x) 'polynomial))
    (define (higher-type x)
      (let ((tail (memq x numeric-tower)))
	(cond ((eq? #f tail) (error "Type not in the tower" x))
	      ((null? (cdr tail)) (error "Already the highest type:" x))
	      (else (cadr tail)))))

    (show #t "Test: Higher than 'integer: " (higher-type 'integer) "\n")
    #;(show #t "Test: Higher than 'complex: " (higher-type 'complex) "\n")

      (define (type1<=type2? type1 type2)
	(if (not (memq type1 numeric-tower))
	    (error "Type 1 not in the numeric tower"))
	(if (not (memq type2 numeric-tower))
	    (error "Type 2 not in the numeric tower"))
	(let loop ((types numeric-tower))
	  (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
		((eq? (car types) type1) #t)
		((eq? (car types) type2) #f)
		(else (loop (cdr types))))))

      #;(define (integer->rational x)
	(make-rational x 1))

      #;(define (rational->scheme-number x)
	(make-scheme-number ((get 'to-real '(rational)) x)))
      #;(put-coercion 'integer 'rational integer->rational)
      #;(put-coercion 'rational 'scheme-number rational->scheme-number)
    (define (integer->scheme-number x)
       (make-scheme-number (contents (exact->inexact x))))
    (put-coercion 'integer 'scheme-number integer->scheme-number)  

    (define (raise-type x)
      #;(show #t "Raising type of: " (displayed x) "\n")
	(let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
	  (if converter
	      (converter x)
	      (error "No coercion found for x" (type-tag x) x))))


      (define (remainder-integer a b)
	(when (or (not (integer? a)) (not (integer? b)))
	  (error "Arguments must be integers" a b))
	(remainder a b))

      (put 'remainder '(integer integer) remainder-integer)
      (define (remainder-generalized a b) (apply-generic 'remainder a b))

      (define (project obj)
	(apply-generic 'project obj))
      (define (droppable? obj)
	#;(show #t "droppable?: obj=" obj ", type-tag=" (type-tag obj) "\n")
	(cond ((eq? (type-tag obj) 'rational) (begin (show #t "rational not droppable: #f\n") #f))
	      ((not (memq (type-tag obj) numeric-tower)) #f)
	      ((eq? (type-tag obj) (car numeric-tower)) #f)
	      ((equ? obj (raise-type (project obj))) #t)
	      (else #f)))
      (define (drop obj) 
	(if (droppable? obj)
	    (drop (project obj))
	    obj))

      (show #t "Test 1: Subtracting complex numbers: "
	    (sub
	     (make-complex-from-real-imag 1.1 2)
	     (make-complex-from-real-imag 0 2)) "\n")
    (define (install-polynomial-package)
      #;(define (contents generic-object)
	(cdr generic-object))
	(define (make-poly variable term-list)
	  (cons variable term-list))
	(define (variable p) (car p))
	(define (term-list p)
	  (cdr p))
	(define (variable? x) (symbol? x))
	(define (same-variable? v1 v2)
	  (and (variable? v1) (variable? v2) (eq? v1 v2)))
	(define (=number? exp num)
	  (and (number? exp) (= exp num)))
	(define (the-empty-termlist) '())

	(define (rest-terms term-list) (cdr term-list))
	(define (empty-termlist? term-list) (null? term-list))

	(define (make-term order coeff) (list order coeff))
	(define (order term) (car term))
	(define (coeff term) (cadr term))
	(define (tag p) (attach-tag 'polynomial p))
	(put 'make 'polynomial
	     (lambda (var terms) (tag (make-poly var terms))))
	#;(continued on next page)

	(define (add-poly p1 p2)
	  #;(show #t "add-poly: p1=" p1 ", p2=" p2 "\n")
	  (if (same-variable? (variable p1) (variable p2))
	      (make-poly (variable p1)
			 (add-terms (term-list p1)
				    (term-list p2)))
	      (let ((res (cdr (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		  (add (tag p1) (tag (make-poly (variable p1) (list (make-term 0 (tag p2))))))
		  (add (tag (make-poly (variable p2) (list (make-term 0 (tag p1))))) (tag p2))))))
		#;(show #t "add-poly:result: " (displayed res) "\n") res)))

	(show #t "TestY2: poly of poly: "
	      (make-poly 'x (list
			     (make-term 3 (make-poly
					   'y (list (make-term 1 1) (make-term 0 1))))
			     (make-term 1 2)
			     (make-term 0 4))) "\n")

	(define (sub-poly p1 p2)
	  (add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
	(define (add-terms L1 L2)
	  (cond ((empty-termlist? L1) L2)
		((empty-termlist? L2) L1)
		(else
		 (let ((t1 (first-term L1)) (t2 (first-term L2)))
		   (cond ((> (order t1) (order t2))
			  (adjoin-term
			   t1 (add-terms (rest-terms L1) L2)))
			 ((< (order t1) (order t2))
			  (adjoin-term
			   t2 (add-terms L1 (rest-terms L2))))
			 (else
			  (adjoin-term
			   (make-term (order t1)
				      (add (coeff t1) (coeff t2)))
			   (add-terms (rest-terms L1)
				      (rest-terms L2)))))))))


	(define (mul-poly p1 p2)
	  (if (same-variable? (variable p1) (variable p2))
	      (make-poly (variable p1)
			 (mul-terms (term-list p1)
				    (term-list p2)))
	      (contents (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		  (mul (tag p1)
		       (make-polynomial (variable p1)
					(adjoin-term
					 (make-term 0
						    (tag p2)) (the-empty-termlist))))
		  (mul (tag p2)
		       (make-polynomial (variable p2)
					(adjoin-term
					 (make-term 0
						    (tag p1)) (the-empty-termlist))))))
	      #;(error "Polys not in same var -- MUL-POLY"
		     (list p1 p2))))
	(define (div-poly p1 p2)
	  (if (same-variable? (variable p1) (variable p2))
	      (let ((quotient-and-remainder (div-terms (term-list p1)
						       (term-list p2))))
		(list (make-poly (variable p1) (car  quotient-and-remainder))
		      (make-poly (variable p1) (cadr quotient-and-remainder))))
		(error "div-poly: Polys not in the same var" p1 p2)))
	(define (div-terms L1 L2)
		(if (empty-termlist? L1)
		    (list (the-empty-termlist) (the-empty-termlist))
		    (let ((t1 (first-term L1))
			  (t2 (first-term L2)))
		      (if (> (order t2) (order t1))
			  (list (the-empty-termlist) L1)
			  (let ((new-c (div (coeff t1) (coeff t2)))
				(new-o (- (order t1) (order t2))))
			    (let ((rest-of-result (div-terms (term-list
							      (sub-poly
							       (make-poly 'fake-var L1)
							       (mul-poly
								(make-poly 'fake-var (list (make-term new-o new-c)))
								(make-poly 'fake-var L2))))
							     L2)
						  ))
			      #;(show #t "div-terms: rest-of-result: " (displayed rest-of-result) "\n")
			      (list (adjoin-term (make-term new-o new-c) (car rest-of-result)) (cadr rest-of-result))
			      ))))))
	(define (gcd-terms a b)
	  (if (empty-termlist? b)
	      a
	      (gcd-terms b (remainder-terms a b))))
	(define (remainder-terms a b)
	  (cadr (div-terms a b)))
	(define (gcd-poly p1 p2)
	  (if (same-variable? (variable p1) (variable p2))
	      (make-poly (variable p1) (gcd-terms (term-list p1) (term-list p2)))
	      (error "div-poly: Polys not in the same var" p1 p2)))
	(put 'gcd '(polynomial polynomial)
	     (lambda (x y) (tag (gcd-poly x y))))
	(put 'gcd '(integer integer) gcd)
      
	(define (mul-terms L1 L2)
	  (if (empty-termlist? L1)
	      (the-empty-termlist)
	      (add-terms (mul-term-by-all-terms (first-term L1) L2)
			 (mul-terms (rest-terms L1) L2))))

	(define (mul-term-by-all-terms t1 L)
	  (if (empty-termlist? L)
	      (the-empty-termlist)
	      (let ((t2 (first-term L)))
		(adjoin-term
		 (make-term (+ (order t1) (order t2))
			    (mul (coeff t1) (coeff t2)))
		 (mul-term-by-all-terms t1 (rest-terms L))))))
	(define (zero-poly? poly)
	  #;(show #t "zero-poly?: poly=" (displayed poly) "\n")
	  (cond ((empty-termlist? (term-list poly)) #t)
		((not (zero? (coeff (first-term (term-list poly))))) #f)
		(else (zero-poly? 
		       (make-poly (variable poly)
				  (rest-terms (term-list poly)))))))

	(define (termlist-type-of term-list)
	  #;(show #t "t-t-o: term-list=" (displayed term-list) "\n")
	  (cond ((null? term-list) 'sparse)
		((pair? (car term-list)) 'sparse)
		((list? term-list) 'dense)
		(else (error "Unknown type of list" term-list))))
	(define (adjoin-term term term-list)
	  ((get 'adjoin-term (termlist-type-of term-list)) term term-list))
	(define (first-term term-list)
	  ((get 'first-term (termlist-type-of term-list)) term-list))
	(define (variable_1-order<variable_2-order variable_1 variable_2)
	  #;(show #t "var_1-..: variable_1=" variable_1 " variable_2=" variable_2 "\n")
	  #;(show #t "var12string=" (symbol->string variable_1) "var22string=" (symbol->string variable_2) "\n")
	  (string<=? (symbol->string variable_1) (symbol->string variable_2)))
	(define (normalize-fully poly)
	  (if (normal-polynomial? poly)
	      poly
	      (normalize-fully (normalize-once poly))))
	(put 'add '(polynomial polynomial)
	     (lambda (p1 p2) 
	       #;(show #t "generic-add-poly:Polynomial dispatch found: p1="
		      (displayed p1) " p2=" (displayed p2) "\n")
	       (normalize-fully (tag (add-poly p1 p2)))))
	(put 'mul '(polynomial polynomial)
	     (lambda (p1 p2) (normalize-fully (tag (mul-poly p1 p2)))))
	(put 'sub '(polynomial polynomial)
	     (lambda (p1 p2) (tag (sub-poly p1 p2))))

	(put 'zero? '(polynomial) zero-poly?)
	(put 'div '(polynomial polynomial) div-poly)
	#;(put-coercion 'rational 'scheme-number rational->scheme-number)
	(define (monomial-flip-variables monomial)
	  #;(show #t "m-f-v: monomial=" monomial "\n")
	  (let* ((mono (contents monomial))
		 (inner-polynomial (contents (coeff (first-term (term-list mono)))))
		 (inner-poly (contents inner-polynomial))
		 (outer-order (order (first-term (term-list mono))))
		 (outer-var (variable mono))
		 (inner-var (variable inner-polynomial))
		 (inner-term-list (term-list inner-poly)))
	    #;(show #t "m-f-v: inner-poly=" inner-poly "\n")
	    (if (same-variable? inner-var outer-var)
		(mul
		 (make-polynomial outer-var (adjoin-term (make-term outer-order 1) (the-empty-termlist)))
		 (tag inner-polynomial))
		(tag (make-poly inner-var
				(mul-term-by-all-terms (make-term
							0
							(make-polynomial
							 outer-var
							 (list (make-term
								outer-order
								1)))) inner-poly))))))
	#;(show #t "TestXX: sorting variables: Is 'x < 'y?: "
	      (variable_1-order<variable_2-order 'x 'y) "\n")
	#;(show #t "TestXX: sorting variables: Is 'z < 'y?: "
	      (variable_1-order<variable_2-order 'z 'y) "\n")
	#;(show #t "TestXX: (adding two basic poly): "
	      (add (make-polynomial 'x (list (make-term 1 2) (make-term 0 4)))
		   (make-polynomial 'y (list (make-term 2 3) (make-term 0 5)))) "\n")

	(define (polynomial->sum-of-first-and-rest poly)
	  #;(show #t "p->s-o-f-a-r: " (displayed poly) "\n")
	  (if (zero? poly)
	      poly
	      (let* ((poly1 (contents poly))
		     (first-monomial (tag
				      (make-poly
				       (variable poly1)
				       (list (first-term (term-list poly1)))))))
		#;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		(add
		  first-monomial
		  (polynomial->sum-of-first-and-rest
		   (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	(show #t "Test13: Expanding a polynomial as monomials: "
	      (displayed
	       (polynomial->sum-of-first-and-rest
		(make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))))) "\n")

	(show #t "\nTest20: start monomial: "
	      (displayed (make-polynomial 'x
					  (list
					   (make-term
					    2
					    (make-polynomial
					     'y
					     (list
					      (make-term 2 1) (make-term 0 1))))))) "\n")
	(show #t "Test20: Flipping a monomial variable: "
	      (displayed
	       (monomial-flip-variables
		(make-polynomial 'x
				 (list (make-term 1 (make-polynomial
						     'y
						     (list
						      (make-term 2 1)
						      (make-term 0 1)))))))) "\n\n")


	(define (normal-polynomial? poly)
	  #;(show #t "n-p?: poly=" poly "\n")
	  (cond ((not (polynomial? poly)) #t)
		((null? (term-list (contents poly))) #t)
		(else (let* ((poly1 (contents poly))
			     (outer-var (variable poly1)))
			#;(show #t "Inner-let: outer-var=" (displayed outer-var) "\n")
			(let loop ((terms (term-list poly1)))
			  #;(show #t "n-p?-loop: terms=" (displayed terms) "\n")
			  (cond ((null? terms) #t)
				((not (polynomial? (coeff (first-term terms)))) (loop (rest-terms terms)))
				((not (variable_1-order<variable_2-order 
				     outer-var
				     (variable (contents (coeff (first-term terms)))))) (begin #;(show #t "wrong variable order \n") #f))
				((not (normal-polynomial? (coeff (first-term terms)))) (begin #;(show #t "not normal poly\n") #f))
				(else (loop (rest-terms terms)))))
			))))
	(define (normalize-once poly)
	  #;(show #t "normalize-once poly= " (displayed poly) "\n")
	  (if (zero? poly)
	      poly
	      (let* ((poly1 (contents poly))
		     (first-monomial (tag
				      (make-poly
				       (variable poly1)
				       (list (make-term
					      (order (first-term (term-list poly1)))
					      (if (polynomial? (coeff (first-term (term-list poly1))))
						  (normalize-once (coeff (first-term (term-list poly1))))
						  (coeff (first-term (term-list poly1))))))))))
		#;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		(add
		 (if (and (polynomial?
			 (coeff
			  (first-term
			   (term-list
			    (contents first-monomial)))))
			(variable_1-order<variable_2-order
			 (variable
			  (contents
			   (coeff
			    (first-term
			     (term-list
			      (contents first-monomial))))))
			 (variable
			  (contents first-monomial))))
		     (monomial-flip-variables first-monomial)
		     first-monomial)
		  (polynomial->sum-of-first-and-rest
		   (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	(show #t "Test21: normal-polynomial?:start: " (displayed (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test21: normal-polynomial?:result:" (normal-polynomial? (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test22: normal-polynomial?-good:start: "
	      (displayed
	       (make-polynomial 'x
				(list (make-term 2 (make-polynomial
						    'y
						    (list (make-term 2 1) (make-term 0 1))))
				      (make-term 0 2)))) "\n")
	(show #t "Test22: normal-polynomial?-good:result:"
	      (normal-polynomial?
	       (make-polynomial 'x
				(list (make-term 2 (make-polynomial
						    'y
						    (list (make-term 2 1) (make-term 0 1))))
				      (make-term 0 2)))) "\n")

	(show #t "Test23:input: normalizing a bad polynomial: "
	      (make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test23:result: normalizing a bad polynomial: "
	      (normalize-once (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test24:input: normalizing a bad polynomial: "
	      (make-polynomial 'x
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test24:result: normalizing a bad polynomial: "
	      (normalize-once (make-polynomial 'x
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")


	(show #t "Test24:input: normalize-fully a bad polynomial: "
	      (make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test24:result: normalize-fully a bad polynomial: "
	      (normalize-fully (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")



	'done)


      (define (install-polynomial-sparse-package)
	(define (coeff term) (cadr term))
	(define (first-term-sparse term-list) (car term-list))
	(define (adjoin-term-sparse term term-list)
	  (if (zero? (coeff term))
	      term-list
	      (cons term term-list)))
	(put 'adjoin-term 'sparse adjoin-term-sparse)
	(put 'first-term 'sparse first-term-sparse)
	'done)
      (install-polynomial-sparse-package)

      (define (install-polynomial-dense-package)
	(define (make-term order coeff) (list order coeff))
	(define (order term) (car term))
	(define (coeff term) (cadr term))

	(define (adjoin-term-dense term term-list)
	    (if (zero? (coeff term))
		term-list
		(if (> (order term) (length term-list))
		    (append (list (coeff term))
			    (make-list (- (order term) (length term-list)) 0)
			    term-list)
		    (error "adjoin-term:Appending a smaller order term. Recheck."))))
	(define (first-term-dense term-list) 
	   #;(show #t "first-term-dense: " (displayed (make-term (car term-list) (length (cdr term-list)))) "\n")
	   (make-term (length (cdr term-list)) (car term-list) ))
	(put 'adjoin-term 'dense adjoin-term-dense)
	(put 'first-term 'dense first-term-dense)
	'done)
      #;(install-polynomial-dense-package)

      (define (make-polynomial var terms)
	((get 'make 'polynomial) var terms))

    (install-polynomial-package)


      #;(show #t "Test 2: Making polynomials: " 
	    (make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
      #;(show #t "Test 3: Zero?: " 
	    (zero? (make-polynomial 'x (list (list 5 1) (list 4 2)))) "\n")
      #;(show #t "Test 4: Adding polynomials: "
	    (add (make-polynomial 'x '((5 1) (4 2) (0 1)))
		 (make-polynomial 'x '((5 1)))) "\n")
      #;(show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

      #;(show #t "Test 5: Subtracting polynomials: "
	    (sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
		 (make-polynomial 'x '((0 1)))) "\n")

      #;(show #t "Test 6: Making a dense polynomial: " (make-polynomial 'x '(1 2 3 4 5)) "\n")
      #;(show #t "Test 7: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(0)))) "\n")
      #;(show #t "Test 8: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(1)))) "\n")
      #;(show #t "Test 9: Adding dense polynomials: "
	    (add (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
      #;(show #t "Test10: Subtracting dense polynomials: "
	    (sub (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
      #;(show #t "Test11: Subtracting dense and sparse polynomials: "
	    (sub (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '((4 2)))) "\n")
      #;(show #t "Test12: Dividing x^2 + 2x + 1 by x+1: "
	    (displayed
	     (div (make-polynomial 'x '((2 1) (1 2) (0 1)))
		  (make-polynomial 'x '(      (1 1) (0 1)))) ) "\n")
      #;(show #t "Test14: Adding polynomials of two variables: "
	    (displayed
	     (add (make-polynomial 'x '((1 1)))
		  (make-polynomial 'y '((1 1))))))
      #;(show #t "Test14: Adding polynomials of two variables, when one of them is nonexistant: "
	    (displayed
	     (add (make-polynomial 'x '((1 1)))
		  (make-polynomial 'y '((0 1))))))
    (show #t "Test25: multiplying different variables: "
	  (displayed (mul (make-polynomial 'x '((1 1)))
			  (make-polynomial 'y '((1 1))))) "\n")
  (begin
  (define p1 (make-polynomial 'x '((2 1) (0 1))))
  (define p2 (make-polynomial 'x '((3 1) (0 1))))
  (define rf (make-rational p2 p1))
  (show #t "Test 26: make-rational-polynomial: " rf "\n")
  (show #t "Test 27: add-rational\n")
  (show #t "Test 27: " (add rf rf) "\n")
  )

  (show #t "Test 28: polynomial-gcd: start\n")
  (define (greatest-common-divisor p1 p2) (apply-generic 'gcd p1 p2))
  (begin
    (define p1 (make-polynomial
		 'x '((4 1) (3 -1) (2 -2) (1 2))))
    (define p2 (make-polynomial 'x '((3 1) (1 -1))))
  
    (show #t "Test 28: polynomial-gcd: " (greatest-common-divisor p1 p2) "\n"))
#+end_src

#+RESULTS:
#+begin_example
Test: Higher than 'integer: scheme-number
Test 1: Subtracting complex numbers: (scheme-number . 1.1)
TestY2: poly of poly: (x (3 (y (1 1) (0 1))) (1 2) (0 4))
Test13: Expanding a polynomial as monomials: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))

Test20: start monomial: (polynomial x (2 (polynomial y (2 1) (0 1))))
Test20: Flipping a monomial variable: (polynomial y (2 (polynomial x (1 1))) (0 (polynomial x (1 1))))

Test21: normal-polynomial?:start: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test21: normal-polynomial?:result:#f
Test22: normal-polynomial?-good:start: (polynomial x (2 (polynomial y (2 1) (0 1))) (0 2))
Test22: normal-polynomial?-good:result:#t
Test23:input: normalizing a bad polynomial: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test23:result: normalizing a bad polynomial: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))
Test24:input: normalizing a bad polynomial: (polynomial x (2 (polynomial x (2 1) (0 1))) (0 2))
Test24:result: normalizing a bad polynomial: (polynomial x (4 1) (2 1) (0 2))
Test24:input: normalize-fully a bad polynomial: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test24:result: normalize-fully a bad polynomial: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))
Test25: multiplying different variables: (polynomial x (1 (polynomial y (1 1))))
Test 26: make-rational-polynomial: (rational (polynomial x (3 1) (0 1)) polynomial x (2 1) (0 1))
Test 27: add-rational
rational not droppable: #f
Test 27: (rational (polynomial x (5 2) (3 2) (2 2) (0 2)) polynomial x (4 1) (2 2) (0 1))
Test 28: polynomial-gcd: start
Test 28: polynomial-gcd: (polynomial x (2 -1) (1 1))
#+end_example

So the answer is \(-x^2 + x\). Now we need to check this. Luckily, the number
of iterations is not very big.

Wolfram Alpha gives me \(x^2 - x\), which is the same thing, I guess.

*** DONE Exercise 2.95 Illustrate the non-integer problem
    CLOSED: [2019-10-28 Mon 11:35]

#+begin_src scheme :exports both :results output
    (define (thingy-source thingy)
      (cond ((lambda? thingy) (list "lambda" (lambda-source thingy)))
	    ((procedure? thingy) (list "procedure" (procedure-name thingy)))
	    ((pair? thingy) (list "pair" (pair-source thingy)))
	    (else "No source? refactor")))

      (define (accumulate op initial sequence)
	(if (null? sequence)
	    initial
	    (accumulate op (op initial (car sequence)) (cdr sequence))))
      (define false #f)
      (define true  #t)
      (define (make-table)
	(let ((local-table (list '*table*)))
	  (define (lookup key-1 key-2)
	    (let ((subtable (assoc key-1 (cdr local-table))))
	      (if subtable
		  (let ((record (assoc key-2 (cdr subtable))))
		    (if record
			(cdr record)
			false))
		  false)))
	  (define (insert! key-1 key-2 value)
	    (let ((subtable (assoc key-1 (cdr local-table))))
	      (if subtable
		  (let ((record (assoc key-2 (cdr subtable))))
		    (if record
			(set-cdr! record value)
			(set-cdr! subtable
				  (cons (cons key-2 value)
					(cdr subtable)))))
		  (set-cdr! local-table
			    (cons (list key-1
					(cons key-2 value))
				  (cdr local-table)))))
	    'ok)
	  (define (dispatch m)
	    (cond ((eq? m 'lookup-proc) lookup)
		  ((eq? m 'insert-proc!) insert!)
		  (else (error "Unknown operation -- TABLE" m))))
	  dispatch))

      (define operation-table (make-table))
      (define get (operation-table 'lookup-proc))
      (define put (operation-table 'insert-proc!))

      (define coercion-table (make-table))
      (define get-coercion (coercion-table 'lookup-proc))
      (define put-coercion (coercion-table 'insert-proc!))

      (define (attach-tag type-tag contents)
	(cons type-tag contents))

      (define (type-tag datum)
	(cond ((pair? datum) (car datum))
	      ((exact-integer? datum) 'integer)
	      ((real? datum) 'scheme-number)
	      (error "Bad tagged datum -- TYPE-TAG" datum)))

    (define (contents datum)
	(cond ((pair? datum) (cdr datum))
	      ((integer? datum) datum)
	      ((real? datum) datum)
	      (else (error "Bad tagged datum -- CONTENTS" datum))))

      (define (integer? x)
	(eq? (type-tag x) 'integer))
      (define (rectangular? z)
	(eq? (type-tag z) 'rectangular))

      (define (polar? z)
	(eq? (type-tag z) 'polar))


      (define (real-part z) (apply-generic 'real-part z))
      (define (imag-part z) (apply-generic 'imag-part z))
      (define (magnitude z) (apply-generic 'magnitude z))
      (define (angle z) (apply-generic 'angle z))

      (define (add x y) (apply-generic 'add x y))
      (define (sub x y) (apply-generic 'sub x y))
      (define (mul x y) (apply-generic 'mul x y))
      (define (div x y) (apply-generic 'div x y))

      (define (equ? x y)
	(apply-generic 'equ? x y))
      (define (zero? x) (apply-generic 'zero? x))

      (define (exp x y) (apply-generic 'exp x y))

      (define (install-scheme-number-package)
	(define (tag x)
	  (attach-tag 'scheme-number x))
	(put 'add '(scheme-number scheme-number)
	     (lambda (x y) (tag (+ x y))))
	(put 'sub '(scheme-number scheme-number)
	     (lambda (x y) (tag (- x y))))
	(put 'mul '(scheme-number scheme-number)
	     (lambda (x y) (tag (* x y))))
	(put 'div '(scheme-number scheme-number)
	     (lambda (x y) (tag (/ x y))))
	(put 'make 'scheme-number
	     (lambda (x) (tag x)))
	(put 'equ? '(scheme-number scheme-number)
	     (lambda (x y) (= x y)))
	(put 'zero? '(scheme-number)
	     (lambda (x) (= 0 x)))
	(put 'exp '(scheme-number scheme-number)
	     (lambda (x y) (tag (expt x y))))
	(put 'project '(scheme-number)
	     (lambda (x)
	       (exact (truncate x))))
	(put 'sine '(scheme-number) sin)
	(put 'cosine '(scheme-number) cos)
	(put 'square-root '(scheme-number) sqrt)
	(put 'arctangent '(schemer-number) atan)
	'done)

      (define (sine x) (apply-generic 'sine x))
      (define (cosine x) (apply-generic 'cosine x))
      (define (square-root x) (apply-generic 'square-root x))
      (define (arctangent x) (apply-generic 'arctangent x))

      (define (make-scheme-number n)
	((get 'make 'scheme-number) n))

      (define (install-rational-package)
	(define (numer x) (car x))
	(define (denom x) (cdr x))
	(define (make-rat n d)
	  #;(let ((g (gcd n d)))
	    (cons (/ n g) (/ d g)))
	    (cons n d))
	(define (add-rat x y)
	  (make-rat (add (mul (numer x) (denom y))
		       (mul (numer y) (denom x)))
		    (mul (denom x) (denom y))))
	(define (sub-rat x y)
	  (make-rat (sub (mul (numer x) (denom y))
		       (mul (numer y) (denom x)))
		    (mul (denom x) (denom y))))
	(define (mul-rat x y)
	  (make-rat (mul (numer x) (numer y))
		    (mul (denom x) (denom y))))
	(define (div-rat x y)
	  (make-rat (mul (numer x) (denom y))
		    (mul (denom x) (numer y))))

	(define (tag x) (attach-tag 'rational x))
	(put 'add '(rational rational)
	     (lambda (x y) (tag (add-rat x y))))
	(put 'sub '(rational rational)
	     (lambda (x y) (tag (sub-rat x y))))
	(put 'mul '(rational rational)
	     (lambda (x y) (tag (mul-rat x y))))
	(put 'div '(rational rational)
	     (lambda (x y) (tag (div-rat x y))))

	(put 'make 'rational
	     (lambda (n d) (tag (make-rat n d))))
	(put 'equ? '(rational rational)
	     (lambda (x y) (zero? (numer (sub-rat x y)))))
	(put 'zero? '(rational) (lambda (x) (zero? (numer x))))
	#;(put 'project '(rational) (lambda (x) 
				    (exact (truncate (/ (numer x) (denom x))))))
	#;(put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
	'done)

      (define (make-rational n d)
	((get 'make 'rational) n d))

      (define (install-rectangular-package)

	(define (real-part z) (car z))
	(define (imag-part z) (cdr z))
	(define (make-from-real-imag x y) (cons x y))
	(define (magnitude z)
	  (square-root (add (square (real-part z))
			    (square (imag-part z)))))
	(define (angle z)
	  (arctangent (imag-part z) (real-part z)))
	(define (make-from-mag-ang r a)
	  (cons (mul r (cosine a)) (mul r (sine a))))

	(define (tag x) (attach-tag 'rectangular x))
	(put 'real-part '(rectangular) real-part)
	(put 'imag-part '(rectangular) imag-part)
	(put 'magnitude '(rectangular) magnitude)
	(put 'angle '(rectangular) angle)
	(put 'make-from-real-imag 'rectangular
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'rectangular
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	'done)

      (define (install-polar-package)

	(define (magnitude z) (car z))
	(define (angle z) (cdr z))
	(define (make-from-mag-ang r a) (cons r a))
	(define (real-part z)
	  (mul (magnitude z) (cosine (angle z))))
	(define (imag-part z)
	  (mul (magnitude z) (sine (angle z))))
	(define (make-from-real-imag x y)
	  (cons (square-root (add (square x) (square y)))
		(arctangent y x)))

	(define (tag x) (attach-tag 'polar x))
	(put 'real-part '(polar) real-part)
	(put 'imag-part '(polar) imag-part)
	(put 'magnitude '(polar) magnitude)
	(put 'angle '(polar) angle)
	(put 'make-from-real-imag 'polar
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'polar
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	'done)

      (define (install-complex-package)
	(define (make-from-real-imag x y)
	  ((get 'make-from-real-imag 'rectangular) x y))
	(define (make-from-mag-ang r a)
	  ((get 'make-from-mag-ang 'polar) r a))
	(define (add-complex z1 z2)
	  (make-from-real-imag (add (real-part z1) (real-part z2))
			       (add (imag-part z1) (imag-part z2))))
	(define (sub-complex z1 z2)
	  (make-from-real-imag (sub (real-part z1) (real-part z2))
			       (sub (imag-part z1) (imag-part z2))))
	(define (mul-complex z1 z2)
	  (make-from-mag-ang (mul (magnitude z1) (magnitude z2))
			     (add (angle z1) (angle z2))))
	(define (div-complex z1 z2)
	  (make-from-mag-ang (div (magnitude z1) (magnitude z2))
			     (sub (angle z1) (angle z2))))
	(define (tag z) (attach-tag 'complex z))
	(put 'add '(complex complex)
	     (lambda (z1 z2) (tag (add-complex z1 z2))))
	(put 'sub '(complex complex)
	     (lambda (z1 z2) (tag (sub-complex z1 z2))))
	(put 'mul '(complex complex)
	     (lambda (z1 z2) (tag (mul-complex z1 z2))))
	(put 'div '(complex complex)
	     (lambda (z1 z2) (tag (div-complex z1 z2))))
	(put 'make-from-real-imag 'complex
	     (lambda (x y) (tag (make-from-real-imag x y))))
	(put 'make-from-mag-ang 'complex
	     (lambda (r a) (tag (make-from-mag-ang r a))))
	(put 'equ? '(complex complex)
	     (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
				(= 0 (imag-part (sub-complex x y))))))
	(put 'equ? '(rectangular polar) equ?)
	(put 'equ? '(polar rectangular) equ?)
	(put 'zero? '(complex)
	     (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
	(put 'project '(complex) (lambda (z) (real-part z)))
	'done)

      (define (make-complex-from-real-imag x y)
	((get 'make-from-real-imag 'complex) x y))

      (define (make-complex-from-mag-ang r a)
	((get 'make-from-mag-ang 'complex) r a))

      (install-rectangular-package)
      (install-polar-package)
      (install-rational-package)
      (install-scheme-number-package)
      (install-complex-package)

      (put 'real-part '(complex) real-part)
      (put 'imag-part '(complex) imag-part)
      (put 'magnitude '(complex) magnitude)
      (put 'angle '(complex) angle)

      (define (apply-generic op . args)
	#;(show #t "apply-generic:entry\n")
	#;(error "debug")
	(define (variable poly) (car poly))
	(define (all-argtypes-same? . args)
	  (let ((type (type-tag (car args))))
	    (accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
	(define (coercion-if-exists? type arg-tags)
	  (let ((coercion-list (map (lambda (x) 
				      (if (eq? type x)
					  identity
					  (get-coercion x type))) arg-tags)))
	    (if (accumulate (lambda (x y) (and x y)) #t coercion-list)
		coercion-list
		#f)))
	(drop (let* ((type-tags (map type-tag args))
		     (proc (get op type-tags)))
		#;(show #t "apply-generic: type-tags=" 
			 (displayed type-tags)
			 " proc=" (written proc)
			 " proc-source=" (thingy-source proc) "\n")
		(cond (proc (apply proc (map contents args)))
		      ((= 1 (length args))
		       #;(show #t "No proc found for op=" op ", type-tags=" type-tags ", arg=" (displayed args) "\n")
		       (apply-generic op (raise-type (car args))))
		      ((= 2 (length args))
		       (cond ((and (eq? 'polynomial (car type-tags))
				 (numeric? (cadr type-tags)))
			      (apply-generic op
					     (car args)
					     (make-polynomial (variable (contents (car args)))
							      (list (list 0 (cadr args))))))
			     ((and (numeric? (car type-tags))
				 (eq? 'polynomial (cadr type-tags)))
			      (apply-generic op
					     (make-polynomial (variable (contents (cadr args)))
							      (list (list 0 (car args))))
					     (cadr args)))			 
			     ((and (get-coercion (car type-tags) (cadr type-tags))
				 (not (eq? (car type-tags) (cadr type-tags))))
			      (apply-generic op
					     ((get-coercion
					       (car type-tags)
					       (cadr type-tags)) (car args))
					     (cadr args)))
			     ((and (get-coercion (cadr type-tags) (car type-tags))
				 (not (eq? (car type-tags) (cadr type-tags))))
			      (apply-generic op
					     (car args)
					     ((get-coercion
					       (cadr type-tags)
					       (car type-tags)) (cadr args) )))
			     ((comparable? (car type-tags) (cadr type-tags))
			      (if
			       (type1<=type2? (car type-tags) (cadr type-tags))
			       (apply-generic op (raise-type (car args)) (cadr args))
			       (apply-generic op (car args)  (raise-type (cadr args)))))
			     (else (error "apply-generic:Incomparable types: (type-tags,args)=" type-tags args))))
		      ((and (> (length args) 2) (not (all-argtypes-same? args)))
		       (let types-loop ((types type-tags))
			 (let ((list-of-coercion-functions
				(coercion-if-exists? (car types) type-tags)))
			   (if list-of-coercion-functions
			       (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
								  list-of-coercion-functions
								  args)))
			       (if (not (null? (cdr types)))
				   (types-loop (cdr types))
				   (error "apply-generic:Even coercions failed. No method for these types."))))))
		      (else (error "apply-generic:No method for these types"
				   (list op type-tags)))))))
      (define (scheme-number->complex n)
	(make-complex-from-real-imag (contents n) 0))
      (put-coercion 'scheme-number
		    'complex
		    scheme-number->complex)

      (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
							(max (magnitude z1) (magnitude z2) (magnitude z3))))
      (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
      (define (identity x) x)

    #;(define numeric-tower (list 'integer 'rational 'scheme-number 'complex))
    (define numeric-tower (list 'integer 'scheme-number 'complex))
    (define (comparable? type1 type2) (and (memq type1 numeric-tower) (memq type2 numeric-tower)))
    #;(define (higher-type x)
      (show #t "higher-type:x=" (displayed x) "\n")
	(define (find-higher-type x types)
	  (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x types))
		((eq? x (car types)) (cadr types))
		(else (find-higher-type x (cdr types)))))
	(find-higher-type x numeric-tower))

    (define (numeric? x)
      (memq x numeric-tower))
    (define (polynomial? x)
      (eq? (type-tag x) 'polynomial))
    (define (higher-type x)
      (let ((tail (memq x numeric-tower)))
	(cond ((eq? #f tail) (error "Type not in the tower" x))
	      ((null? (cdr tail)) (error "Already the highest type:" x))
	      (else (cadr tail)))))

    (show #t "Test: Higher than 'integer: " (higher-type 'integer) "\n")
    #;(show #t "Test: Higher than 'complex: " (higher-type 'complex) "\n")

      (define (type1<=type2? type1 type2)
	(if (not (memq type1 numeric-tower))
	    (error "Type 1 not in the numeric tower"))
	(if (not (memq type2 numeric-tower))
	    (error "Type 2 not in the numeric tower"))
	(let loop ((types numeric-tower))
	  (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
		((eq? (car types) type1) #t)
		((eq? (car types) type2) #f)
		(else (loop (cdr types))))))

      #;(define (integer->rational x)
	(make-rational x 1))

      #;(define (rational->scheme-number x)
	(make-scheme-number ((get 'to-real '(rational)) x)))
      #;(put-coercion 'integer 'rational integer->rational)
      #;(put-coercion 'rational 'scheme-number rational->scheme-number)
    (define (integer->scheme-number x)
       (make-scheme-number (contents (exact->inexact x))))
    (put-coercion 'integer 'scheme-number integer->scheme-number)  

    (define (raise-type x)
      #;(show #t "Raising type of: " (displayed x) "\n")
	(let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
	  (if converter
	      (converter x)
	      (error "No coercion found for x" (type-tag x) x))))


      (define (remainder-integer a b)
	(when (or (not (integer? a)) (not (integer? b)))
	  (error "Arguments must be integers" a b))
	(remainder a b))

      (put 'remainder '(integer integer) remainder-integer)
      (define (remainder-generalized a b) (apply-generic 'remainder a b))

      (define (project obj)
	(apply-generic 'project obj))
      (define (droppable? obj)
	#;(show #t "droppable?: obj=" obj ", type-tag=" (type-tag obj) "\n")
	(cond ((eq? (type-tag obj) 'rational) (begin (show #t "rational not droppable: #f\n") #f))
	      ((not (memq (type-tag obj) numeric-tower)) #f)
	      ((eq? (type-tag obj) (car numeric-tower)) #f)
	      ((equ? obj (raise-type (project obj))) #t)
	      (else #f)))
      (define (drop obj) 
	(if (droppable? obj)
	    (drop (project obj))
	    obj))

      (show #t "Test 1: Subtracting complex numbers: "
	    (sub
	     (make-complex-from-real-imag 1.1 2)
	     (make-complex-from-real-imag 0 2)) "\n")
    (define (install-polynomial-package)
      #;(define (contents generic-object)
	(cdr generic-object))
	(define (make-poly variable term-list)
	  (cons variable term-list))
	(define (variable p) (car p))
	(define (term-list p)
	  (cdr p))
	(define (variable? x) (symbol? x))
	(define (same-variable? v1 v2)
	  (and (variable? v1) (variable? v2) (eq? v1 v2)))
	(define (=number? exp num)
	  (and (number? exp) (= exp num)))
	(define (the-empty-termlist) '())

	(define (rest-terms term-list) (cdr term-list))
	(define (empty-termlist? term-list) (null? term-list))

	(define (make-term order coeff) (list order coeff))
	(define (order term) (car term))
	(define (coeff term) (cadr term))
	(define (tag p) (attach-tag 'polynomial p))
	(put 'make 'polynomial
	     (lambda (var terms) (tag (make-poly var terms))))
	#;(continued on next page)

	(define (add-poly p1 p2)
	  #;(show #t "add-poly: p1=" p1 ", p2=" p2 "\n")
	  (if (same-variable? (variable p1) (variable p2))
	      (make-poly (variable p1)
			 (add-terms (term-list p1)
				    (term-list p2)))
	      (let ((res (cdr (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		  (add (tag p1) (tag (make-poly (variable p1) (list (make-term 0 (tag p2))))))
		  (add (tag (make-poly (variable p2) (list (make-term 0 (tag p1))))) (tag p2))))))
		#;(show #t "add-poly:result: " (displayed res) "\n") res)))

	(show #t "TestY2: poly of poly: "
	      (make-poly 'x (list
			     (make-term 3 (make-poly
					   'y (list (make-term 1 1) (make-term 0 1))))
			     (make-term 1 2)
			     (make-term 0 4))) "\n")

	(define (sub-poly p1 p2)
	  (add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
	(define (add-terms L1 L2)
	  (cond ((empty-termlist? L1) L2)
		((empty-termlist? L2) L1)
		(else
		 (let ((t1 (first-term L1)) (t2 (first-term L2)))
		   (cond ((> (order t1) (order t2))
			  (adjoin-term
			   t1 (add-terms (rest-terms L1) L2)))
			 ((< (order t1) (order t2))
			  (adjoin-term
			   t2 (add-terms L1 (rest-terms L2))))
			 (else
			  (adjoin-term
			   (make-term (order t1)
				      (add (coeff t1) (coeff t2)))
			   (add-terms (rest-terms L1)
				      (rest-terms L2)))))))))


	(define (mul-poly p1 p2)
	  (if (same-variable? (variable p1) (variable p2))
	      (make-poly (variable p1)
			 (mul-terms (term-list p1)
				    (term-list p2)))
	      (contents (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		  (mul (tag p1)
		       (make-polynomial (variable p1)
					(adjoin-term
					 (make-term 0
						    (tag p2)) (the-empty-termlist))))
		  (mul (tag p2)
		       (make-polynomial (variable p2)
					(adjoin-term
					 (make-term 0
						    (tag p1)) (the-empty-termlist))))))
	      #;(error "Polys not in same var -- MUL-POLY"
		     (list p1 p2))))
	(define (div-poly p1 p2)
	  (if (same-variable? (variable p1) (variable p2))
	      (let ((quotient-and-remainder (div-terms (term-list p1)
						       (term-list p2))))
		(list (make-poly (variable p1) (car  quotient-and-remainder))
		      (make-poly (variable p1) (cadr quotient-and-remainder))))
		(error "div-poly: Polys not in the same var" p1 p2)))
	(define (div-terms L1 L2)
		(if (empty-termlist? L1)
		    (list (the-empty-termlist) (the-empty-termlist))
		    (let ((t1 (first-term L1))
			  (t2 (first-term L2)))
		      (if (> (order t2) (order t1))
			  (list (the-empty-termlist) L1)
			  (let ((new-c (div (coeff t1) (coeff t2)))
				(new-o (- (order t1) (order t2))))
			    (let ((rest-of-result (div-terms (term-list
							      (sub-poly
							       (make-poly 'fake-var L1)
							       (mul-poly
								(make-poly 'fake-var (list (make-term new-o new-c)))
								(make-poly 'fake-var L2))))
							     L2)
						  ))
			      #;(show #t "div-terms: rest-of-result: " (displayed rest-of-result) "\n")
			      (list (adjoin-term (make-term new-o new-c) (car rest-of-result)) (cadr rest-of-result))
			      ))))))
	(define (gcd-terms a b)
	  (if (empty-termlist? b)
	      a
	      (begin 
              (show #t "gcd-terms: (term-list b)=" (term-list b) "\n")
              (gcd-terms b (remainder-terms a b)))))
	(define (remainder-terms a b)
	  (cadr (div-terms a b)))
	(define (gcd-poly p1 p2)
	  (if (same-variable? (variable p1) (variable p2))
	      (make-poly (variable p1) (gcd-terms (term-list p1) (term-list p2)))
	      (error "div-poly: Polys not in the same var" p1 p2)))
	(put 'gcd '(polynomial polynomial)
	     (lambda (x y) (tag (gcd-poly x y))))
	(put 'gcd '(integer integer) gcd)
      
	(define (mul-terms L1 L2)
	  (if (empty-termlist? L1)
	      (the-empty-termlist)
	      (add-terms (mul-term-by-all-terms (first-term L1) L2)
			 (mul-terms (rest-terms L1) L2))))

	(define (mul-term-by-all-terms t1 L)
	  (if (empty-termlist? L)
	      (the-empty-termlist)
	      (let ((t2 (first-term L)))
		(adjoin-term
		 (make-term (+ (order t1) (order t2))
			    (mul (coeff t1) (coeff t2)))
		 (mul-term-by-all-terms t1 (rest-terms L))))))
	(define (zero-poly? poly)
	  #;(show #t "zero-poly?: poly=" (displayed poly) "\n")
	  (cond ((empty-termlist? (term-list poly)) #t)
		((not (zero? (coeff (first-term (term-list poly))))) #f)
		(else (zero-poly? 
		       (make-poly (variable poly)
				  (rest-terms (term-list poly)))))))

	(define (termlist-type-of term-list)
	  #;(show #t "t-t-o: term-list=" (displayed term-list) "\n")
	  (cond ((null? term-list) 'sparse)
		((pair? (car term-list)) 'sparse)
		((list? term-list) 'dense)
		(else (error "Unknown type of list" term-list))))
	(define (adjoin-term term term-list)
	  ((get 'adjoin-term (termlist-type-of term-list)) term term-list))
	(define (first-term term-list)
	  ((get 'first-term (termlist-type-of term-list)) term-list))
	(define (variable_1-order<variable_2-order variable_1 variable_2)
	  #;(show #t "var_1-..: variable_1=" variable_1 " variable_2=" variable_2 "\n")
	  #;(show #t "var12string=" (symbol->string variable_1) "var22string=" (symbol->string variable_2) "\n")
	  (string<=? (symbol->string variable_1) (symbol->string variable_2)))
	(define (normalize-fully poly)
	  (if (normal-polynomial? poly)
	      poly
	      (normalize-fully (normalize-once poly))))
	(put 'add '(polynomial polynomial)
	     (lambda (p1 p2) 
	       #;(show #t "generic-add-poly:Polynomial dispatch found: p1="
		      (displayed p1) " p2=" (displayed p2) "\n")
	       (normalize-fully (tag (add-poly p1 p2)))))
	(put 'mul '(polynomial polynomial)
	     (lambda (p1 p2) (normalize-fully (tag (mul-poly p1 p2)))))
	(put 'sub '(polynomial polynomial)
	     (lambda (p1 p2) (tag (sub-poly p1 p2))))

	(put 'zero? '(polynomial) zero-poly?)
	(put 'div '(polynomial polynomial) div-poly)
	#;(put-coercion 'rational 'scheme-number rational->scheme-number)
	(define (monomial-flip-variables monomial)
	  #;(show #t "m-f-v: monomial=" monomial "\n")
	  (let* ((mono (contents monomial))
		 (inner-polynomial (contents (coeff (first-term (term-list mono)))))
		 (inner-poly (contents inner-polynomial))
		 (outer-order (order (first-term (term-list mono))))
		 (outer-var (variable mono))
		 (inner-var (variable inner-polynomial))
		 (inner-term-list (term-list inner-poly)))
	    #;(show #t "m-f-v: inner-poly=" inner-poly "\n")
	    (if (same-variable? inner-var outer-var)
		(mul
		 (make-polynomial outer-var (adjoin-term (make-term outer-order 1) (the-empty-termlist)))
		 (tag inner-polynomial))
		(tag (make-poly inner-var
				(mul-term-by-all-terms (make-term
							0
							(make-polynomial
							 outer-var
							 (list (make-term
								outer-order
								1)))) inner-poly))))))
	#;(show #t "TestXX: sorting variables: Is 'x < 'y?: "
	      (variable_1-order<variable_2-order 'x 'y) "\n")
	#;(show #t "TestXX: sorting variables: Is 'z < 'y?: "
	      (variable_1-order<variable_2-order 'z 'y) "\n")
	#;(show #t "TestXX: (adding two basic poly): "
	      (add (make-polynomial 'x (list (make-term 1 2) (make-term 0 4)))
		   (make-polynomial 'y (list (make-term 2 3) (make-term 0 5)))) "\n")

	(define (polynomial->sum-of-first-and-rest poly)
	  #;(show #t "p->s-o-f-a-r: " (displayed poly) "\n")
	  (if (zero? poly)
	      poly
	      (let* ((poly1 (contents poly))
		     (first-monomial (tag
				      (make-poly
				       (variable poly1)
				       (list (first-term (term-list poly1)))))))
		#;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		(add
		  first-monomial
		  (polynomial->sum-of-first-and-rest
		   (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	(show #t "Test13: Expanding a polynomial as monomials: "
	      (displayed
	       (polynomial->sum-of-first-and-rest
		(make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))))) "\n")

	(show #t "\nTest20: start monomial: "
	      (displayed (make-polynomial 'x
					  (list
					   (make-term
					    2
					    (make-polynomial
					     'y
					     (list
					      (make-term 2 1) (make-term 0 1))))))) "\n")
	(show #t "Test20: Flipping a monomial variable: "
	      (displayed
	       (monomial-flip-variables
		(make-polynomial 'x
				 (list (make-term 1 (make-polynomial
						     'y
						     (list
						      (make-term 2 1)
						      (make-term 0 1)))))))) "\n\n")


	(define (normal-polynomial? poly)
	  #;(show #t "n-p?: poly=" poly "\n")
	  (cond ((not (polynomial? poly)) #t)
		((null? (term-list (contents poly))) #t)
		(else (let* ((poly1 (contents poly))
			     (outer-var (variable poly1)))
			#;(show #t "Inner-let: outer-var=" (displayed outer-var) "\n")
			(let loop ((terms (term-list poly1)))
			  #;(show #t "n-p?-loop: terms=" (displayed terms) "\n")
			  (cond ((null? terms) #t)
				((not (polynomial? (coeff (first-term terms)))) (loop (rest-terms terms)))
				((not (variable_1-order<variable_2-order 
				     outer-var
				     (variable (contents (coeff (first-term terms)))))) (begin #;(show #t "wrong variable order \n") #f))
				((not (normal-polynomial? (coeff (first-term terms)))) (begin #;(show #t "not normal poly\n") #f))
				(else (loop (rest-terms terms)))))
			))))
	(define (normalize-once poly)
	  #;(show #t "normalize-once poly= " (displayed poly) "\n")
	  (if (zero? poly)
	      poly
	      (let* ((poly1 (contents poly))
		     (first-monomial (tag
				      (make-poly
				       (variable poly1)
				       (list (make-term
					      (order (first-term (term-list poly1)))
					      (if (polynomial? (coeff (first-term (term-list poly1))))
						  (normalize-once (coeff (first-term (term-list poly1))))
						  (coeff (first-term (term-list poly1))))))))))
		#;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		(add
		 (if (and (polynomial?
			 (coeff
			  (first-term
			   (term-list
			    (contents first-monomial)))))
			(variable_1-order<variable_2-order
			 (variable
			  (contents
			   (coeff
			    (first-term
			     (term-list
			      (contents first-monomial))))))
			 (variable
			  (contents first-monomial))))
		     (monomial-flip-variables first-monomial)
		     first-monomial)
		  (polynomial->sum-of-first-and-rest
		   (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	(show #t "Test21: normal-polynomial?:start: " (displayed (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test21: normal-polynomial?:result:" (normal-polynomial? (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test22: normal-polynomial?-good:start: "
	      (displayed
	       (make-polynomial 'x
				(list (make-term 2 (make-polynomial
						    'y
						    (list (make-term 2 1) (make-term 0 1))))
				      (make-term 0 2)))) "\n")
	(show #t "Test22: normal-polynomial?-good:result:"
	      (normal-polynomial?
	       (make-polynomial 'x
				(list (make-term 2 (make-polynomial
						    'y
						    (list (make-term 2 1) (make-term 0 1))))
				      (make-term 0 2)))) "\n")

	(show #t "Test23:input: normalizing a bad polynomial: "
	      (make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test23:result: normalizing a bad polynomial: "
	      (normalize-once (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")
	(show #t "Test24:input: normalizing a bad polynomial: "
	      (make-polynomial 'x
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test24:result: normalizing a bad polynomial: "
	      (normalize-once (make-polynomial 'x
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")


	(show #t "Test24:input: normalize-fully a bad polynomial: "
	      (make-polynomial 'y
				 (list (make-term 2 (make-polynomial
						     'x
						     (list (make-term 2 1) (make-term 0 1))))
				       (make-term 0 2))) "\n")
	(show #t "Test24:result: normalize-fully a bad polynomial: "
	      (normalize-fully (make-polynomial 'y
					       (list (make-term 2 (make-polynomial
								   'x
						     (list (make-term 2 1) (make-term 0 1))))
						     (make-term 0 2)))) "\n")



	'done)


      (define (install-polynomial-sparse-package)
	(define (coeff term) (cadr term))
	(define (first-term-sparse term-list) (car term-list))
	(define (adjoin-term-sparse term term-list)
	  (if (zero? (coeff term))
	      term-list
	      (cons term term-list)))
	(put 'adjoin-term 'sparse adjoin-term-sparse)
	(put 'first-term 'sparse first-term-sparse)
	'done)
      (install-polynomial-sparse-package)

      (define (install-polynomial-dense-package)
	(define (make-term order coeff) (list order coeff))
	(define (order term) (car term))
	(define (coeff term) (cadr term))

	(define (adjoin-term-dense term term-list)
	    (if (zero? (coeff term))
		term-list
		(if (> (order term) (length term-list))
		    (append (list (coeff term))
			    (make-list (- (order term) (length term-list)) 0)
			    term-list)
		    (error "adjoin-term:Appending a smaller order term. Recheck."))))
	(define (first-term-dense term-list) 
	   #;(show #t "first-term-dense: " (displayed (make-term (car term-list) (length (cdr term-list)))) "\n")
	   (make-term (length (cdr term-list)) (car term-list) ))
	(put 'adjoin-term 'dense adjoin-term-dense)
	#;(put 'first-term 'dense first-term-dense)
	'done)
      #;(install-polynomial-dense-package)

      (define (make-polynomial var terms)
	((get 'make 'polynomial) var terms))

    (install-polynomial-package)


      #;(show #t "Test 2: Making polynomials: " 
	    (make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
      #;(show #t "Test 3: Zero?: " 
	    (zero? (make-polynomial 'x (list (list 5 1) (list 4 2)))) "\n")
      #;(show #t "Test 4: Adding polynomials: "
	    (add (make-polynomial 'x '((5 1) (4 2) (0 1)))
		 (make-polynomial 'x '((5 1)))) "\n")
      #;(show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

      #;(show #t "Test 5: Subtracting polynomials: "
	    (sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
		 (make-polynomial 'x '((0 1)))) "\n")

      #;(show #t "Test 6: Making a dense polynomial: " (make-polynomial 'x '(1 2 3 4 5)) "\n")
      #;(show #t "Test 7: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(0)))) "\n")
      #;(show #t "Test 8: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(1)))) "\n")
      #;(show #t "Test 9: Adding dense polynomials: "
	    (add (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
      #;(show #t "Test10: Subtracting dense polynomials: "
	    (sub (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
      #;(show #t "Test11: Subtracting dense and sparse polynomials: "
	    (sub (make-polynomial 'x '(1 2 0 0 0 1))
		 (make-polynomial 'x '((4 2)))) "\n")
      #;(show #t "Test12: Dividing x^2 + 2x + 1 by x+1: "
	    (displayed
	     (div (make-polynomial 'x '((2 1) (1 2) (0 1)))
		  (make-polynomial 'x '(      (1 1) (0 1)))) ) "\n")
      #;(show #t "Test14: Adding polynomials of two variables: "
	    (displayed
	     (add (make-polynomial 'x '((1 1)))
		  (make-polynomial 'y '((1 1))))))
      #;(show #t "Test14: Adding polynomials of two variables, when one of them is nonexistant: "
	    (displayed
	     (add (make-polynomial 'x '((1 1)))
		  (make-polynomial 'y '((0 1))))))
    (show #t "Test25: multiplying different variables: "
	  (displayed (mul (make-polynomial 'x '((1 1)))
			  (make-polynomial 'y '((1 1))))) "\n")
  (begin
  (define p1 (make-polynomial 'x '((2 1) (0 1))))
  (define p2 (make-polynomial 'x '((3 1) (0 1))))
  (define rf (make-rational p2 p1))
  (show #t "Test 26: make-rational-polynomial: " rf "\n")
  (show #t "Test 27: add-rational\n")
  (show #t "Test 27: " (add rf rf) "\n")
  )

  (show #t "Test 28: polynomial-gcd: start\n")
  (define (greatest-common-divisor p1 p2) (apply-generic 'gcd p1 p2))
  (begin
    (define p1 (make-polynomial
		 'x '((4 1) (3 -1) (2 -2) (1 2))))
    (define p2 (make-polynomial 'x '((3 1) (1 -1))))
  
    (show #t "Test 28: polynomial-gcd: " (greatest-common-divisor p1 p2) "\n"))

  (begin
      (define p1 (make-polynomial
		   'x '((2 1) (1 -2) (0 1))))
      (define p2 (make-polynomial 'x '((2 11) (0 7))))

      (define p3 (make-polynomial 'x '((1 13) (0 5))))
      (define q1 (mul p1 p2))
      (define q2 (mul p1 p3))
      (show #t "Test 29: gcd-integer-problem: start\n")
      (show #t "Test 29: gcd : " (greatest-common-divisor q1 q2) "\n")      
    )
#+end_src

#+RESULTS:
#+begin_example
Test: Higher than 'integer: scheme-number
Test 1: Subtracting complex numbers: (scheme-number . 1.1)
TestY2: poly of poly: (x (3 (y (1 1) (0 1))) (1 2) (0 4))
Test13: Expanding a polynomial as monomials: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))

Test20: start monomial: (polynomial x (2 (polynomial y (2 1) (0 1))))
Test20: Flipping a monomial variable: (polynomial y (2 (polynomial x (1 1))) (0 (polynomial x (1 1))))

Test21: normal-polynomial?:start: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test21: normal-polynomial?:result:#f
Test22: normal-polynomial?-good:start: (polynomial x (2 (polynomial y (2 1) (0 1))) (0 2))
Test22: normal-polynomial?-good:result:#t
Test23:input: normalizing a bad polynomial: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test23:result: normalizing a bad polynomial: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))
Test24:input: normalizing a bad polynomial: (polynomial x (2 (polynomial x (2 1) (0 1))) (0 2))
Test24:result: normalizing a bad polynomial: (polynomial x (4 1) (2 1) (0 2))
Test24:input: normalize-fully a bad polynomial: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test24:result: normalize-fully a bad polynomial: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))
Test25: multiplying different variables: (polynomial x (1 (polynomial y (1 1))))
Test 26: make-rational-polynomial: (rational (polynomial x (3 1) (0 1)) polynomial x (2 1) (0 1))
Test 27: add-rational
rational not droppable: #f
Test 27: (rational (polynomial x (5 2) (3 2) (2 2) (0 2)) polynomial x (4 1) (2 2) (0 1))
Test 28: polynomial-gcd: start
gcd-terms: (term-list b)=((1 -1))
gcd-terms: (term-list b)=((1 1))
Test 28: polynomial-gcd: (polynomial x (2 -1) (1 1))
Test 29: gcd-integer-problem: start
gcd-terms: (term-list b)=((2 -21) (1 3) (0 5))
gcd-terms: (term-list b)=((1 (scheme-number . -17.254437869822485)) (0 (scheme-number . 8.627218934911243)))
gcd-terms: (term-list b)=((0 (scheme-number . 7.993605777301127e-15)))
gcd-terms: (term-list b)=()
Test 29: gcd : (polynomial x (0 (scheme-number . 1.100410578432558)))
#+end_example

The answer is a polynomial \(x^0 \times 1.100410578432558\), which is
essentially just a number. Clearly, this is not the greatest common
divisor. I believe, this problem happens because at some point, the
comparison "(if (= 0 b))" fails, because b is very small, but still nonzero
due to precision problems. In principle, this should be possible to fix by
carefully studying the algorithm and ensuring that every operation in
"div-terms" preserves exactness. Still, this should give a polynomial with
very long coefficients.

When I was doing the manual repetition of the algorithm, I found that the
numerators and denominators of the numbers grow very fast, so it quickly
becomes very hard to operate with these numbers.
*** DONE Exercise 2.96 Integerizing factor
    CLOSED: [2019-10-28 Mon 19:23]

This is not a very hard exercise. The only problem here is still the messy
part in the division by the gcd, but hey, formally the exercise is done.

#+begin_src scheme :exports both :results output

	(define (thingy-source thingy)
	  (cond ((lambda? thingy) (list "lambda" (lambda-source thingy)))
		((procedure? thingy) (list "procedure" (procedure-name thingy)))
		((pair? thingy) (list "pair" (pair-source thingy)))
		(else "No source? refactor")))

	  (define (accumulate op initial sequence)
	    (if (null? sequence)
		initial
		(accumulate op (op initial (car sequence)) (cdr sequence))))
	  (define false #f)
	  (define true  #t)
	  (define (make-table)
	    (let ((local-table (list '*table*)))
	      (define (lookup key-1 key-2)
		(let ((subtable (assoc key-1 (cdr local-table))))
		  (if subtable
		      (let ((record (assoc key-2 (cdr subtable))))
			(if record
			    (cdr record)
			    false))
		      false)))
	      (define (insert! key-1 key-2 value)
		(let ((subtable (assoc key-1 (cdr local-table))))
		  (if subtable
		      (let ((record (assoc key-2 (cdr subtable))))
			(if record
			    (set-cdr! record value)
			    (set-cdr! subtable
				      (cons (cons key-2 value)
					    (cdr subtable)))))
		      (set-cdr! local-table
				(cons (list key-1
					    (cons key-2 value))
				      (cdr local-table)))))
		'ok)
	      (define (dispatch m)
		(cond ((eq? m 'lookup-proc) lookup)
		      ((eq? m 'insert-proc!) insert!)
		      (else (error "Unknown operation -- TABLE" m))))
	      dispatch))

	  (define operation-table (make-table))
	  (define get (operation-table 'lookup-proc))
	  (define put (operation-table 'insert-proc!))

	  (define coercion-table (make-table))
	  (define get-coercion (coercion-table 'lookup-proc))
	  (define put-coercion (coercion-table 'insert-proc!))

	  (define (attach-tag type-tag contents)
	    (cons type-tag contents))

	  (define (type-tag datum)
	    (cond ((pair? datum) (car datum))
		  ((exact-integer? datum) 'integer)
		  ((real? datum) 'scheme-number)
		  (error "Bad tagged datum -- TYPE-TAG" datum)))

	(define (contents datum)
	    (cond ((pair? datum) (cdr datum))
		  ((integer? datum) datum)
		  ((real? datum) datum)
		  (else (error "Bad tagged datum -- CONTENTS" datum))))

	  (define (integer? x)
	    (eq? (type-tag x) 'integer))
	  (define (rectangular? z)
	    (eq? (type-tag z) 'rectangular))

	  (define (polar? z)
	    (eq? (type-tag z) 'polar))


	  (define (real-part z) (apply-generic 'real-part z))
	  (define (imag-part z) (apply-generic 'imag-part z))
	  (define (magnitude z) (apply-generic 'magnitude z))
	  (define (angle z) (apply-generic 'angle z))

	  (define (add x y) 
	     #;(show #t "debug:add: x=" x ", y=" y ", starting apply-generic\n")
	     #;(show #t "debug:add: (type-tags x,y)=(" (type-tag x) "," (type-tag y) ")" "\n")
	     #;(show #t "debug:add:can we access apply-generic?" (written apply-generic)
		      "\n" )
	     #;(error "Debug1")
	     (apply-generic 'add x y))
	  (define (sub x y) (apply-generic 'sub x y))
	  (define (mul x y) (apply-generic 'mul x y))
	  (define (div x y) (apply-generic 'div x y))

	  (define (equ? x y)
	    (apply-generic 'equ? x y))
	  (define (zero? x) (apply-generic 'zero? x))

	  (define (exp x y) (apply-generic 'exp x y))

	  (define (install-scheme-number-package)
	    (define (tag x)
	      #;(attach-tag 'scheme-number x) x)
	    (show #t "(tag 5)=" (tag 5) "\n")
	    (put 'add '(scheme-number scheme-number)
		 (lambda (x y) #;(show #t "debug:found plus dispatch\n") (tag (+ x y))))
	    (put 'sub '(scheme-number scheme-number)
		 (lambda (x y) (tag (- x y))))
	    (put 'mul '(scheme-number scheme-number)
		 (lambda (x y) (tag (* x y))))
	    (put 'div '(scheme-number scheme-number)
		 (lambda (x y) (tag (/ x y))))
	    (put 'make 'scheme-number
		 (lambda (x) #;(show #t "debug:found 'make 'scheme-number\n") (tag x)))
	    (put 'equ? '(scheme-number scheme-number)
		 (lambda (x y) (= x y)))
	    (put 'zero? '(scheme-number)
		 (lambda (x) (= 0 x)))
	    (put 'exp '(scheme-number scheme-number)
		 (lambda (x y) (tag (expt x y))))
	    (put 'project '(scheme-number)
		 (lambda (x)
		   (if (finite? x)
                      (exact (truncate x))
                      0)))
	    (put 'sine '(scheme-number) sin)
	    (put 'cosine '(scheme-number) cos)
	    (put 'square-root '(scheme-number) sqrt)
	    (put 'arctangent '(schemer-number) atan)
	    'done)
  (install-scheme-number-package)
	(define (integer->scheme-number x)
	   (make-scheme-number (inexact (contents x))))
	(put-coercion 'integer 'scheme-number integer->scheme-number)  

	  (define (sine x) (apply-generic 'sine x))
	  (define (cosine x) (apply-generic 'cosine x))
	  (define (square-root x) (apply-generic 'square-root x))
	  (define (arctangent x) (apply-generic 'arctangent x))

	  (define (make-scheme-number n)
	     #;(show #t "debug:make-scheme-number: n=" n "\n")
	    ((get 'make 'scheme-number) n))
	  #;(check (+ 1 1) => 2)
	  (show #t "Test 31: start\n")
	  (show #t "Test 31:" (equal? (make-scheme-number 1) 1) "\n")

	  #;(check (add (make-scheme-number 1) (make-scheme-number 1)) => 2)

	  (define (install-rational-package)
	    (define (numer x) (car x))
	    (define (denom x) (cdr x))
	    (define (make-rat n d)
	      #;(let ((g (gcd n d)))
		(cons (/ n g) (/ d g)))
		(cons n d))
	    (define (add-rat x y)
	      (make-rat (add (mul (numer x) (denom y))
			   (mul (numer y) (denom x)))
			(mul (denom x) (denom y))))
	    (define (sub-rat x y)
	      (make-rat (sub (mul (numer x) (denom y))
			   (mul (numer y) (denom x)))
			(mul (denom x) (denom y))))
	    (define (mul-rat x y)
	      (make-rat (mul (numer x) (numer y))
			(mul (denom x) (denom y))))
	    (define (div-rat x y)
	      (make-rat (mul (numer x) (denom y))
			(mul (denom x) (numer y))))

	    (define (tag x) (attach-tag 'rational x))
	    (put 'add '(rational rational)
		 (lambda (x y) (tag (add-rat x y))))
	    (put 'sub '(rational rational)
		 (lambda (x y) (tag (sub-rat x y))))
	    (put 'mul '(rational rational)
		 (lambda (x y) (tag (mul-rat x y))))
	    (put 'div '(rational rational)
		 (lambda (x y) (tag (div-rat x y))))

	    (put 'make 'rational
		 (lambda (n d) (tag (make-rat n d))))
	    (put 'equ? '(rational rational)
		 (lambda (x y) (zero? (numer (sub-rat x y)))))
	    (put 'zero? '(rational) (lambda (x) (zero? (numer x))))
	    #;(put 'project '(rational) (lambda (x) 
					(exact (truncate (/ (numer x) (denom x))))))
	    #;(put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
	    'done)

	  (define (make-rational n d)
	    ((get 'make 'rational) n d))

	  (define (install-rectangular-package)

	    (define (real-part z) (car z))
	    (define (imag-part z) (cdr z))
	    (define (make-from-real-imag x y) (cons x y))
	    (define (magnitude z)
	      (square-root (add (square (real-part z))
				(square (imag-part z)))))
	    (define (angle z)
	      (arctangent (imag-part z) (real-part z)))
	    (define (make-from-mag-ang r a)
	      (cons (mul r (cosine a)) (mul r (sine a))))

	    (define (tag x) (attach-tag 'rectangular x))
	    (put 'real-part '(rectangular) real-part)
	    (put 'imag-part '(rectangular) imag-part)
	    (put 'magnitude '(rectangular) magnitude)
	    (put 'angle '(rectangular) angle)
	    (put 'make-from-real-imag 'rectangular
		 (lambda (x y) (tag (make-from-real-imag x y))))
	    (put 'make-from-mag-ang 'rectangular
		 (lambda (r a) (tag (make-from-mag-ang r a))))
	    'done)

	  (define (install-polar-package)

	    (define (magnitude z) (car z))
	    (define (angle z) (cdr z))
	    (define (make-from-mag-ang r a) (cons r a))
	    (define (real-part z)
	      (mul (magnitude z) (cosine (angle z))))
	    (define (imag-part z)
	      (mul (magnitude z) (sine (angle z))))
	    (define (make-from-real-imag x y)
	      (cons (square-root (add (square x) (square y)))
		    (arctangent y x)))

	    (define (tag x) (attach-tag 'polar x))
	    (put 'real-part '(polar) real-part)
	    (put 'imag-part '(polar) imag-part)
	    (put 'magnitude '(polar) magnitude)
	    (put 'angle '(polar) angle)
	    (put 'make-from-real-imag 'polar
		 (lambda (x y) (tag (make-from-real-imag x y))))
	    (put 'make-from-mag-ang 'polar
		 (lambda (r a) (tag (make-from-mag-ang r a))))
	    'done)

	  (define (install-complex-package)
	    (define (make-from-real-imag x y)
	      ((get 'make-from-real-imag 'rectangular) x y))
	    (define (make-from-mag-ang r a)
	      ((get 'make-from-mag-ang 'polar) r a))
	    (define (add-complex z1 z2)
	      (make-from-real-imag (add (real-part z1) (real-part z2))
				   (add (imag-part z1) (imag-part z2))))
	    (define (sub-complex z1 z2)
	      (make-from-real-imag (sub (real-part z1) (real-part z2))
				   (sub (imag-part z1) (imag-part z2))))
	    (define (mul-complex z1 z2)
	      (make-from-mag-ang (mul (magnitude z1) (magnitude z2))
				 (add (angle z1) (angle z2))))
	    (define (div-complex z1 z2)
	      (make-from-mag-ang (div (magnitude z1) (magnitude z2))
				 (sub (angle z1) (angle z2))))
	    (define (tag z) (attach-tag 'complex z))
	    (put 'add '(complex complex)
		 (lambda (z1 z2) (tag (add-complex z1 z2))))
	    (put 'sub '(complex complex)
		 (lambda (z1 z2) (tag (sub-complex z1 z2))))
	    (put 'mul '(complex complex)
		 (lambda (z1 z2) (tag (mul-complex z1 z2))))
	    (put 'div '(complex complex)
		 (lambda (z1 z2) (tag (div-complex z1 z2))))
	    (put 'make-from-real-imag 'complex
		 (lambda (x y) (tag (make-from-real-imag x y))))
	    (put 'make-from-mag-ang 'complex
		 (lambda (r a) (tag (make-from-mag-ang r a))))
	    (put 'equ? '(complex complex)
		 (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
				    (= 0 (imag-part (sub-complex x y))))))
	    (put 'equ? '(rectangular polar) equ?)
	    (put 'equ? '(polar rectangular) equ?)
	    (put 'zero? '(complex)
		 (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
	    (put 'project '(complex) (lambda (z) (real-part z)))
	    'done)

	  (define (make-complex-from-real-imag x y)
	    ((get 'make-from-real-imag 'complex) x y))

	  (define (make-complex-from-mag-ang r a)
	    ((get 'make-from-mag-ang 'complex) r a))

	  (install-rectangular-package)
	  (install-polar-package)
	  (install-rational-package)

	  (install-complex-package)

	  (put 'real-part '(complex) real-part)
	  (put 'imag-part '(complex) imag-part)
	  (put 'magnitude '(complex) magnitude)
	  (put 'angle '(complex) angle)
	  (define (polynomial? x)
	    (eq? (type-tag x) 'polynomial))
	  (define numeric-tower (list 'integer 'scheme-number 'complex))
	  (define (numeric? x)
	    (memq x numeric-tower))
	  (define (type1<=type2? type1 type2)
	    (if (not (memq type1 numeric-tower))
		(error "Type 1 not in the numeric tower"))
	    (if (not (memq type2 numeric-tower))
		(error "Type 2 not in the numeric tower"))
	    (let loop ((types numeric-tower))
	      (cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
		    ((eq? (car types) type1) #t)
		    ((eq? (car types) type2) #f)
		    (else (loop (cdr types))))))
	  (define (comparable? type1 type2) 
	    (and (memq type1 numeric-tower) 
		(memq type2 numeric-tower)))
	  (define (raise-type x)
	  #;(show #t "Raising type of: " (displayed x) "\n")
	    (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
	      (if converter
		  (converter x)
		  (error "No coercion found for x" (type-tag x) x))))
	(define (higher-type x)
	  (let ((tail (memq x numeric-tower)))
	    (cond ((eq? #f tail) (error "Type not in the tower" x))
		  ((null? (cdr tail)) (error "Already the highest type:" x))
		  (else (cadr tail)))))

	(show #t "Test: Higher than 'integer: " (higher-type 'integer) "\n")
	  (define (remainder-integer a b)
	    (when (or (not (integer? a)) (not (integer? b)))
	      (error "Arguments must be integers" a b))
	    (remainder a b))

	  (put 'remainder '(integer integer) remainder-integer)
	  (define (remainder-generalized a b) (apply-generic 'remainder a b))

	  (define (project obj)
	    (apply-generic 'project obj))
	  (define (droppable? obj)
	    #;(show #t "droppable?: obj=" obj ", type-tag=" (type-tag obj) "\n")
	    (cond ((eq? (type-tag obj) 'rational) (begin (show #t "rational not droppable: #f\n") #f))
		  ((not (memq (type-tag obj) numeric-tower)) #f)
		  ((eq? (type-tag obj) (car numeric-tower)) #f)
		  ((equ? obj (raise-type (project obj))) #t)
		  (else #f)))
	  (define (drop obj) 
	    (if (droppable? obj)
		(drop (project obj))
		obj))

	  (define (apply-generic op . args)
	    #;(show #t "apply-generic:entry\n")
	    #;(error "debug")
	    (define (variable poly) (car poly))
	    (define (all-argtypes-same? . args)
	      (let ((type (type-tag (car args))))
		(accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
	    (define (coercion-if-exists? type arg-tags)
	      (let ((coercion-list (map (lambda (x) 
					  (if (eq? type x)
					      identity
					      (get-coercion x type))) arg-tags)))
		(if (accumulate (lambda (x y) (and x y)) #t coercion-list)
		    coercion-list
		    #f)))
	    (drop (let* ((type-tags (map type-tag args))
			 (proc (get op type-tags)))
		   #;(show #t "apply-generic: type-tags=" 
			     (displayed type-tags)
			     " proc=" (written proc)
			     " proc-source=" (thingy-source proc) "\n")
		    (cond (proc (apply proc (map contents args)))
			  ((= 1 (length args))
		   #;(show #t "No proc found for op=" op ", type-tags=" type-tags ", arg=" (displayed args) "\n")
			   (apply-generic op (raise-type (car args))))
			  ((= 2 (length args))
			   (cond ((and (eq? 'polynomial (car type-tags))
				     (numeric? (cadr type-tags)))
				  (apply-generic op
						 (car args)
						 (make-polynomial (variable (contents (car args)))
								  (list (list 0 (cadr args))))))
				 ((and (numeric? (car type-tags))
			       (eq? 'polynomial (cadr type-tags)))
				  (apply-generic op
						 (make-polynomial (variable (contents (cadr args)))
								  (list (list 0 (car args))))
						 (cadr args)))			 
				 ((and (get-coercion (car type-tags) (cadr type-tags))
				     (not (eq? (car type-tags) (cadr type-tags))))
				  (apply-generic op
						 ((get-coercion
						   (car type-tags)
						   (cadr type-tags)) (car args))
						 (cadr args)))
				 ((and (get-coercion (cadr type-tags) (car type-tags))
				     (not (eq? (car type-tags) (cadr type-tags))))
				  (apply-generic op
						 (car args)
						 ((get-coercion
						   (cadr type-tags)
						   (car type-tags)) (cadr args) )))
				 ((comparable? (car type-tags) (cadr type-tags))
				  (if
				   (type1<=type2? (car type-tags) (cadr type-tags))
				   (apply-generic op (raise-type (car args)) (cadr args))
				   (apply-generic op (car args)  (raise-type (cadr args)))))
				 (else (error "apply-generic:Incomparable types: (type-tags,args)=" type-tags args))))
			  ((and (> (length args) 2) (not (all-argtypes-same? args)))
			   (let types-loop ((types type-tags))
			     (let ((list-of-coercion-functions
				    (coercion-if-exists? (car types) type-tags)))
			       (if list-of-coercion-functions
				   (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
								      list-of-coercion-functions
								      args)))
				   (if (not (null? (cdr types)))
				       (types-loop (cdr types))
				       (error "apply-generic:Even coercions failed. No method for these types."))))))
			  (else (error "apply-generic:No method for these types"
				       (list op type-tags)))))))
	  (show #t "Test 30: start\n")
	  (show #t "Test 30:(add (make-scheme-number 1) (make-scheme-number 1))= "
	     (add (make-scheme-number 1) (make-scheme-number 1)) "\n")
	  #;(error "Debug6")
	  (define (scheme-number->complex n)
	    (make-complex-from-real-imag (contents n) 0))
	  (put-coercion 'scheme-number
			'complex
			scheme-number->complex)

	  (show #t "Test 32: start")
	  (show #t "Test 32: Subtracting complex numbers: "
		(sub
		 (make-complex-from-real-imag 1.1 2)
		 (make-complex-from-real-imag 0 2)) "\n")



	  (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
							    (max (magnitude z1) (magnitude z2) (magnitude z3))))
	  (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
	  (define (identity x) x)

	#;(define numeric-tower (list 'integer 'rational 'scheme-number 'complex))


	#;(define (higher-type x)
	  (show #t "higher-type:x=" (displayed x) "\n")
	    (define (find-higher-type x types)
	      (cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x types))
		    ((eq? x (car types)) (cadr types))
		    (else (find-higher-type x (cdr types)))))
	    (find-higher-type x numeric-tower))

	#;(show #t "Test: Higher than 'complex: " (higher-type 'complex) "\n")

	  #;(define (integer->rational x)
	    (make-rational x 1))

	  #;(define (rational->scheme-number x)
	    (make-scheme-number ((get 'to-real '(rational)) x)))
	  #;(put-coercion 'integer 'rational integer->rational)
	  #;(put-coercion 'rational 'scheme-number rational->scheme-number)

	(define (install-polynomial-package)
	  #;(define (contents generic-object)
	    (cdr generic-object))
	    (define (make-poly variable term-list)
	      (cons variable term-list))
	    (define (variable p) (car p))
	    (define (term-list p)
	      (cdr p))
	    (define (variable? x) (symbol? x))
	    (define (same-variable? v1 v2)
	      (and (variable? v1) (variable? v2) (eq? v1 v2)))
	    (define (=number? exp num)
	      (and (number? exp) (= exp num)))
	    (define (the-empty-termlist) '())

	    (define (rest-terms term-list) (cdr term-list))
	    (define (empty-termlist? term-list) (null? term-list))

	    (define (make-term order coeff) (list order coeff))
	    (define (order term) (car term))
	    (define (coeff term) (cadr term))
	    (define (tag p) (attach-tag 'polynomial p))
	    (put 'make 'polynomial
		 (lambda (var terms) (tag (make-poly var terms))))
	    #;(continued on next page)

	    (define (add-poly p1 p2)
	      #;(show #t "add-poly: p1=" p1 ", p2=" p2 "\n")
	      (if (same-variable? (variable p1) (variable p2))
		  (make-poly (variable p1)
			     (add-terms (term-list p1)
					(term-list p2)))
		  (let ((res (cdr (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		      (add (tag p1) (tag (make-poly (variable p1) (list (make-term 0 (tag p2))))))
		      (add (tag (make-poly (variable p2) (list (make-term 0 (tag p1))))) (tag p2))))))
		    #;(show #t "add-poly:result: " (displayed res) "\n") res)))

	    (show #t "TestY2: poly of poly: "
		  (make-poly 'x (list
				 (make-term 3 (make-poly
					       'y (list (make-term 1 1) (make-term 0 1))))
				 (make-term 1 2)
				 (make-term 0 4))) "\n")

	    (define (sub-poly p1 p2)
	      (add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
	    (define (add-terms L1 L2)
	      (cond ((empty-termlist? L1) L2)
		    ((empty-termlist? L2) L1)
		    (else
		     (let ((t1 (first-term L1)) (t2 (first-term L2)))
		       (cond ((> (order t1) (order t2))
			      (adjoin-term
			       t1 (add-terms (rest-terms L1) L2)))
			     ((< (order t1) (order t2))
			      (adjoin-term
			       t2 (add-terms L1 (rest-terms L2))))
			     (else
			      (adjoin-term
			       (make-term (order t1)
					  (add (coeff t1) (coeff t2)))
			       (add-terms (rest-terms L1)
					  (rest-terms L2)))))))))


	    (define (mul-poly p1 p2)
	      (if (same-variable? (variable p1) (variable p2))
		  (make-poly (variable p1)
			     (mul-terms (term-list p1)
					(term-list p2)))
		  (contents (if (variable_1-order<variable_2-order (variable p1) (variable p2))
		      (mul (tag p1)
			   (make-polynomial (variable p1)
					    (adjoin-term
					     (make-term 0
							(tag p2)) (the-empty-termlist))))
		      (mul (tag p2)
			   (make-polynomial (variable p2)
					    (adjoin-term
					     (make-term 0
							(tag p1)) (the-empty-termlist))))))
		  #;(error "Polys not in same var -- MUL-POLY"
			 (list p1 p2))))
	    (define (div-poly p1 p2)
	      (if (same-variable? (variable p1) (variable p2))
		  (let ((quotient-and-remainder (div-terms (term-list p1)
							   (term-list p2))))
		    (list (make-poly (variable p1) (car  quotient-and-remainder))
			  (make-poly (variable p1) (cadr quotient-and-remainder))))
		    (error "div-poly: Polys not in the same var" p1 p2)))
	    (define (div-terms L1 L2)
                    (show #t "div-terms: L1=" L1 ", L2=" L2 "\n")
		    (if (empty-termlist? L1)
			(list (the-empty-termlist) (the-empty-termlist))
			(let ((t1 (first-term L1))
			      (t2 (first-term L2)))
			  (if (> (order t2) (order t1))
			      (list (the-empty-termlist) L1)
			      (let ((new-c (div (coeff t1) (coeff t2)))
				    (new-o (- (order t1) (order t2))))
				(let ((rest-of-result (div-terms (term-list
								  (sub-poly
								   (make-poly 'fake-var L1)
								   (mul-poly
								    (make-poly 'fake-var (list (make-term new-o new-c)))
								    (make-poly 'fake-var L2))))
								 L2)
						      ))
				  #;(show #t "div-terms: rest-of-result: " (displayed rest-of-result) "\n")
				  (list (adjoin-term (make-term new-o new-c) (car rest-of-result)) (cadr rest-of-result))
				  ))))))
	    (define (gcd-terms a b)
            (show #t "gcd-terms: a=" a ", b=" b "\n")
	      (if (empty-termlist? b)
		  a
		  (gcd-terms b (pseudoremainder-terms a b))))
	    (define (pseudoremainder-terms P Q)
	      (let ((O1 (order (first-term P)))
		    (O2 (order (first-term Q)))
		    (c  (coeff (first-term Q))))
                 (show #t "pseudoremainder-terms: P=" P "\n")
                 (show #t "pseudoremainder-terms: Q=" Q "\n")
                 (show #t "pseudoremainder-terms: O1=" O1 "\n")
                 (show #t "pseudoremainder-terms: O2=" O2 "\n")
                 (show #t "pseudoremainder-terms: c=" c "\n")

                 (show #t "pseudoremainder-terms: the integerizing factor="
                    (make-term 0 (exp c (add 1 (sub O1 O2)))) "\n" )
                 (show #t "pseudoremainder-terms: P after multiplication="
                   (mul-term-by-all-terms 
				       (make-term 0 (exp c (add 1 (sub O1 O2)))) P)  "\n" )
		 (cadr (div-terms (mul-term-by-all-terms 
				       (make-term 0 (exp c (add 1 (sub O1 O2)))) P) Q))))

	    (define (gcd-poly p1 p2)
              (show #t "gcd-poly:p1=" p1 ", p2=" p2 "\n") 
              (define (maprest operation term-list)
                   (if (empty-termlist? term-list)
                       '()
                       (cons (operation term-list) (maprest operation (rest-terms term-list))))
              ) 
	      (if (same-variable? (variable p1) (variable p2))
		  (let* ((unoptimized-termlist (gcd-terms (term-list p1) (term-list p2)))
                         (first-terms (maprest first-term unoptimized-termlist))
                        (coefficients (map coeff first-terms))
                        (coeff-gcd (apply gcd coefficients))
                        (optimized-termlist (mul-term-by-all-terms 
				       (make-term 0 (div 1 coeff-gcd)) unoptimized-termlist)))
                     (show #t "gcd-poly: unoptimized-termlist=" unoptimized-termlist "\n")
                     (show #t "gcd-poly: first-terms=" first-terms "\n")
                     (show #t "gcd-poly: coefficients=" coefficients "\n")
                     (show #t "gcd-poly: coeff-gcd=" coeff-gcd "\n")
                     (make-poly (variable p1) optimized-termlist))
		  (error "div-poly: Polys not in the same var" p1 p2)))
	    (put 'gcd '(polynomial polynomial)
		 (lambda (x y) (tag (gcd-poly x y))))
	    (put 'gcd '(integer integer) gcd)

	    (define (mul-terms L1 L2)
	      (if (empty-termlist? L1)
		  (the-empty-termlist)
		  (add-terms (mul-term-by-all-terms (first-term L1) L2)
			     (mul-terms (rest-terms L1) L2))))

	    (define (mul-term-by-all-terms t1 L)
	      (if (empty-termlist? L)
		  (the-empty-termlist)
		  (let ((t2 (first-term L)))
		    (adjoin-term
		     (make-term (+ (order t1) (order t2))
				(mul (coeff t1) (coeff t2)))
		     (mul-term-by-all-terms t1 (rest-terms L))))))
	    (define (zero-poly? poly)
	      (show #t "zero-poly?: poly=" (displayed poly) "\n")
	      (cond ((empty-termlist? (term-list poly)) #t)
		    ((not (zero? (coeff (first-term (term-list poly))))) #f)
		    (else (zero-poly? 
			   (make-poly (variable poly)
				      (rest-terms (term-list poly)))))))

	    (define (termlist-type-of term-list)
	      #;(show #t "t-t-o: term-list=" (displayed term-list) "\n")
	      (cond ((null? term-list) 'sparse)
		    ((pair? (car term-list)) 'sparse)
		    ((list? term-list) 'dense)
		    (else (error "Unknown type of list" term-list))))
	    (define (adjoin-term term term-list)
	      ((get 'adjoin-term (termlist-type-of term-list)) term term-list))
	    (define (first-term term-list)
	      ((get 'first-term (termlist-type-of term-list)) term-list))
	    (define (variable_1-order<variable_2-order variable_1 variable_2)
	      #;(show #t "var_1-..: variable_1=" variable_1 " variable_2=" variable_2 "\n")
	      #;(show #t "var12string=" (symbol->string variable_1) "var22string=" (symbol->string variable_2) "\n")
	      (string<=? (symbol->string variable_1) (symbol->string variable_2)))
	    (define (normalize-fully poly)
	      (if (normal-polynomial? poly)
		  poly
		  (normalize-fully (normalize-once poly))))
	    (put 'add '(polynomial polynomial)
		 (lambda (p1 p2) 
		   #;(show #t "generic-add-poly:Polynomial dispatch found: p1="
			  (displayed p1) " p2=" (displayed p2) "\n")
		   (normalize-fully (tag (add-poly p1 p2)))))
	    (put 'mul '(polynomial polynomial)
		 (lambda (p1 p2) (normalize-fully (tag (mul-poly p1 p2)))))
	    (put 'sub '(polynomial polynomial)
		 (lambda (p1 p2) (tag (sub-poly p1 p2))))

	    (put 'zero? '(polynomial) zero-poly?)
	    (put 'div '(polynomial polynomial) div-poly)
	    #;(put-coercion 'rational 'scheme-number rational->scheme-number)
	    (define (monomial-flip-variables monomial)
	      #;(show #t "m-f-v: monomial=" monomial "\n")
	      (let* ((mono (contents monomial))
		     (inner-polynomial (contents (coeff (first-term (term-list mono)))))
		     (inner-poly (contents inner-polynomial))
		     (outer-order (order (first-term (term-list mono))))
		     (outer-var (variable mono))
		     (inner-var (variable inner-polynomial))
		     (inner-term-list (term-list inner-poly)))
		#;(show #t "m-f-v: inner-poly=" inner-poly "\n")
		(if (same-variable? inner-var outer-var)
		    (mul
		     (make-polynomial outer-var (adjoin-term (make-term outer-order 1) (the-empty-termlist)))
		     (tag inner-polynomial))
		    (tag (make-poly inner-var
				    (mul-term-by-all-terms (make-term
							    0
							    (make-polynomial
							     outer-var
							     (list (make-term
								    outer-order
								    1)))) inner-poly))))))
	    #;(show #t "TestXX: sorting variables: Is 'x < 'y?: "
		  (variable_1-order<variable_2-order 'x 'y) "\n")
	    #;(show #t "TestXX: sorting variables: Is 'z < 'y?: "
		  (variable_1-order<variable_2-order 'z 'y) "\n")
	    #;(show #t "TestXX: (adding two basic poly): "
		  (add (make-polynomial 'x (list (make-term 1 2) (make-term 0 4)))
		       (make-polynomial 'y (list (make-term 2 3) (make-term 0 5)))) "\n")

	    (define (polynomial->sum-of-first-and-rest poly)
	      #;(show #t "p->s-o-f-a-r: " (displayed poly) "\n")
	      (if (zero? poly)
		  poly
		  (let* ((poly1 (contents poly))
			 (first-monomial (tag
					  (make-poly
					   (variable poly1)
					   (list (first-term (term-list poly1)))))))
		    #;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		    (add
		      first-monomial
		      (polynomial->sum-of-first-and-rest
		       (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	    (show #t "Test13: Expanding a polynomial as monomials: "
		  (displayed
		   (polynomial->sum-of-first-and-rest
		    (make-polynomial 'y
				     (list (make-term 2 (make-polynomial
							 'x
							 (list (make-term 2 1) (make-term 0 1))))
					   (make-term 0 2))))) "\n")

	    (show #t "\nTest20: start monomial: "
		  (displayed (make-polynomial 'x
					      (list
					       (make-term
						2
						(make-polynomial
						 'y
						 (list
						  (make-term 2 1) (make-term 0 1))))))) "\n")
	    (show #t "Test20: Flipping a monomial variable: "
		  (displayed
		   (monomial-flip-variables
		    (make-polynomial 'x
				     (list (make-term 1 (make-polynomial
							 'y
							 (list
							  (make-term 2 1)
							  (make-term 0 1)))))))) "\n\n")


	    (define (normal-polynomial? poly)
	      #;(show #t "n-p?: poly=" poly "\n")
	      (cond ((not (polynomial? poly)) #t)
		    ((null? (term-list (contents poly))) #t)
		    (else (let* ((poly1 (contents poly))
				 (outer-var (variable poly1)))
			    #;(show #t "Inner-let: outer-var=" (displayed outer-var) "\n")
			    (let loop ((terms (term-list poly1)))
			      #;(show #t "n-p?-loop: terms=" (displayed terms) "\n")
			      (cond ((null? terms) #t)
				    ((not (polynomial? (coeff (first-term terms)))) (loop (rest-terms terms)))
				    ((not (variable_1-order<variable_2-order 
					 outer-var
					 (variable (contents (coeff (first-term terms)))))) (begin #;(show #t "wrong variable order \n") #f))
				    ((not (normal-polynomial? (coeff (first-term terms)))) (begin #;(show #t "not normal poly\n") #f))
				    (else (loop (rest-terms terms)))))
			    ))))
	    (define (normalize-once poly)
	      #;(show #t "normalize-once poly= " (displayed poly) "\n")
	      (if (zero? poly)
		  poly
		  (let* ((poly1 (contents poly))
			 (first-monomial (tag
					  (make-poly
					   (variable poly1)
					   (list (make-term
						  (order (first-term (term-list poly1)))
						  (if (polynomial? (coeff (first-term (term-list poly1))))
						      (normalize-once (coeff (first-term (term-list poly1))))
						      (coeff (first-term (term-list poly1))))))))))
		    #;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		    (add
		     (if (and (polynomial?
			     (coeff
			      (first-term
			       (term-list
				(contents first-monomial)))))
			    (variable_1-order<variable_2-order
			     (variable
			      (contents
			       (coeff
				(first-term
				 (term-list
				  (contents first-monomial))))))
			     (variable
			      (contents first-monomial))))
			 (monomial-flip-variables first-monomial)
			 first-monomial)
		      (polynomial->sum-of-first-and-rest
		       (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	    (show #t "Test21: normal-polynomial?:start: " (displayed (make-polynomial 'y
						   (list (make-term 2 (make-polynomial
								       'x
							 (list (make-term 2 1) (make-term 0 1))))
							 (make-term 0 2)))) "\n")
	    #;(show #t "Test21: normal-polynomial?:result:" (normal-polynomial? (make-polynomial 'y
						   (list (make-term 2 (make-polynomial
								       'x
							 (list (make-term 2 1) (make-term 0 1))))
							 (make-term 0 2)))) "\n")
	    #;(show #t "Test22: normal-polynomial?-good:start: "
		  (displayed
		   (make-polynomial 'x
				    (list (make-term 2 (make-polynomial
							'y
							(list (make-term 2 1) (make-term 0 1))))
					  (make-term 0 2)))) "\n")
	    #;(show #t "Test22: normal-polynomial?-good:result:"
		  (normal-polynomial?
		   (make-polynomial 'x
				    (list (make-term 2 (make-polynomial
							'y
							(list (make-term 2 1) (make-term 0 1))))
					  (make-term 0 2)))) "\n")

	    #;(show #t "Test23:input: normalizing a bad polynomial: "
		  (make-polynomial 'y
				     (list (make-term 2 (make-polynomial
							 'x
							 (list (make-term 2 1) (make-term 0 1))))
					   (make-term 0 2))) "\n")
	    #;(show #t "Test23:result: normalizing a bad polynomial: "
		  (normalize-once (make-polynomial 'y
						   (list (make-term 2 (make-polynomial
								       'x
							 (list (make-term 2 1) (make-term 0 1))))
							 (make-term 0 2)))) "\n")
	    #;(show #t "Test24:input: normalizing a bad polynomial: "
		  (make-polynomial 'x
				     (list (make-term 2 (make-polynomial
							 'x
							 (list (make-term 2 1) (make-term 0 1))))
					   (make-term 0 2))) "\n")
	    #;(show #t "Test24:result: normalizing a bad polynomial: "
		  (normalize-once (make-polynomial 'x
						   (list (make-term 2 (make-polynomial
								       'x
							 (list (make-term 2 1) (make-term 0 1))))
							 (make-term 0 2)))) "\n")


	    #;(show #t "Test24:input: normalize-fully a bad polynomial: "
		  (make-polynomial 'y
				     (list (make-term 2 (make-polynomial
							 'x
							 (list (make-term 2 1) (make-term 0 1))))
					   (make-term 0 2))) "\n")
	    #;(show #t "Test24:result: normalize-fully a bad polynomial: "
		  (normalize-fully (make-polynomial 'y
						   (list (make-term 2 (make-polynomial
								       'x
							 (list (make-term 2 1) (make-term 0 1))))
							 (make-term 0 2)))) "\n")



	    'done)


	  (define (install-polynomial-sparse-package)
	    (define (coeff term) (cadr term))
	    (define (first-term-sparse term-list) (car term-list))
	    (define (adjoin-term-sparse term term-list)
	      (if (zero? (coeff term))
		  term-list
		  (cons term term-list)))
	    (put 'adjoin-term 'sparse adjoin-term-sparse)
	    (put 'first-term 'sparse first-term-sparse)
	    'done)
	  (install-polynomial-sparse-package)

	  (define (install-polynomial-dense-package)
	    (define (make-term order coeff) (list order coeff))
	    (define (order term) (car term))
	    (define (coeff term) (cadr term))

	    (define (adjoin-term-dense term term-list)
		(if (zero? (coeff term))
		    term-list
		    (if (> (order term) (length term-list))
			(append (list (coeff term))
				(make-list (- (order term) (length term-list)) 0)
				term-list)
			(error "adjoin-term:Appending a smaller order term. Recheck."))))
	    (define (first-term-dense term-list) 
	       #;(show #t "first-term-dense: " (displayed (make-term (car term-list) (length (cdr term-list)))) "\n")
	       (make-term (length (cdr term-list)) (car term-list) ))
	    (put 'adjoin-term 'dense adjoin-term-dense)
	    (put 'first-term 'dense first-term-dense)
	    'done)
	  #;(install-polynomial-dense-package)

	  (define (make-polynomial var terms)
	    ((get 'make 'polynomial) var terms))

	(install-polynomial-package)


	  (show #t "Test 2: Making polynomials: " 
		(make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
	  (show #t "Test 3: Zero?: " 
		(zero? (make-polynomial 'x (list (list 5 1) (list 4 2)))) "\n")
	  (show #t "Test 4: Adding polynomials: "
		(add (make-polynomial 'x '((5 1) (4 2) (0 1)))
		     (make-polynomial 'x '((5 1)))) "\n")
	  (show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

	  (show #t "Test 5: Subtracting polynomials: "
		(sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
		     (make-polynomial 'x '((0 1)))) "\n")

	  #;(show #t "Test 6: Making a dense polynomial: " (make-polynomial 'x '(1 2 3 4 5)) "\n")
	  #;(show #t "Test 7: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(0)))) "\n")
	  #;(show #t "Test 8: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(1)))) "\n")
	  #;(show #t "Test 9: Adding dense polynomials: "
		(add (make-polynomial 'x '(1 2 0 0 0 1))
		     (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
	  #;(show #t "Test10: Subtracting dense polynomials: "
		(sub (make-polynomial 'x '(1 2 0 0 0 1))
		     (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
	  #;(show #t "Test11: Subtracting dense and sparse polynomials: "
		(sub (make-polynomial 'x '(1 2 0 0 0 1))
		     (make-polynomial 'x '((4 2)))) "\n")
	  (show #t "Test12: Dividing x^2 + 2x + 1 by x+1: "
		(displayed
		 (div (make-polynomial 'x '((2 1) (1 2) (0 1)))
		      (make-polynomial 'x '(      (1 1) (0 1)))) ) "\n")
	  (show #t "Test14: Adding polynomials of two variables: "
		(displayed
		 (add (make-polynomial 'x '((1 1)))
		      (make-polynomial 'y '((1 1))))))
	  (show #t "Test14: Adding polynomials of two variables, when one of them is nonexistant: "
		(displayed
		 (add (make-polynomial 'x '((1 1)))
		      (make-polynomial 'y '((0 1))))))
	  (show #t "Test25: multiplying different variables: "
	      (displayed (mul (make-polynomial 'x '((1 1)))
			      (make-polynomial 'y '((1 1))))) "\n")
      (begin
      (define p1 (make-polynomial 'x '((2 1) (0 1))))
      (define p2 (make-polynomial 'x '((3 1) (0 1))))
      (define rf (make-rational p2 p1))
      (show #t "Test 26: make-rational-polynomial: " rf "\n")
      (show #t "Test 27: add-rational\n")
      (show #t "Test 27: " (add rf rf) "\n")
      )

      (show #t "Test 28: polynomial-gcd: start\n")
      (define (greatest-common-divisor p1 p2) (apply-generic 'gcd p1 p2))
      (begin
	(define p1 (make-polynomial
		     'x '((4 1) (3 -1) (2 -2) (1 2))))
	(define p2 (make-polynomial 'x '((3 1) (1 -1))))

	(show #t "Test 28: polynomial-gcd: " (greatest-common-divisor p1 p2) "\n"))

      (begin
	  (define p1 (make-polynomial
		       'x '((2 1) (1 -2) (0 1))))
	  (define p2 (make-polynomial 'x '((2 11) (0 7))))

	  (define p3 (make-polynomial 'x '((1 13) (0 5))))
	  (define q1 (mul p1 p2))
	  (define q2 (mul p1 p3))
	  (show #t "Test 29: gcd-integer-problem: start\n")
          (show #t "Test 29: p1=" p1 "\n")
          (show #t "Test 29: p2=" p2 "\n")
          (show #t "Test 29: p3=" p3 "\n")
          (show #t "Test 29: q1=" q1 "\n")
          (show #t "Test 29: q2=" q2 "\n")
	  (show #t "Test 29: gcd : " (greatest-common-divisor q1 q2) "\n")      
	)

#+end_src

#+RESULTS:
#+begin_example
(tag 5)=5
Test 31: start
Test 31:#t
Test: Higher than 'integer: scheme-number
Test 30: start
Test 30:(add (make-scheme-number 1) (make-scheme-number 1))= 2
Test 32: startTest 32: Subtracting complex numbers: 1.1
TestY2: poly of poly: (x (3 (y (1 1) (0 1))) (1 2) (0 4))
zero-poly?: poly=(y (2 (polynomial x (2 1) (0 1))) (0 2))
zero-poly?: poly=(x (2 1) (0 1))
zero-poly?: poly=(y (0 2))
zero-poly?: poly=(y)
zero-poly?: poly=(x (2 1) (0 1))
zero-poly?: poly=(y (2 (polynomial x (2 1) (0 1))) (0 2))
zero-poly?: poly=(x (2 1) (0 1))
zero-poly?: poly=(x (2 1) (0 1))
zero-poly?: poly=(x (0 1))
zero-poly?: poly=(x)
zero-poly?: poly=(y (0 2))
zero-poly?: poly=(y)
zero-poly?: poly=(y (2 1))
zero-poly?: poly=(y (2 1))
zero-poly?: poly=(y (2 1) (0 2))
zero-poly?: poly=(y (2 1))
Test13: Expanding a polynomial as monomials: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))

Test20: start monomial: (polynomial x (2 (polynomial y (2 1) (0 1))))
zero-poly?: poly=(x (1 1))
zero-poly?: poly=(x (1 1))
Test20: Flipping a monomial variable: (polynomial y (2 (polynomial x (1 1))) (0 (polynomial x (1 1))))

Test21: normal-polynomial?:start: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test 2: Making polynomials: (polynomial x (5 1) (4 2))
zero-poly?: poly=(x (5 1) (4 2))
Test 3: Zero?: #f
Test 4: Adding polynomials: (polynomial x (5 2) (4 2) (0 1))
zero-poly?: poly=(x (5 0) (3 1))
zero-poly?: poly=(x (3 1))
Test 4: Zero?: #f
Test 5: Subtracting polynomials: (polynomial x (5 1) (4 2))
div-terms: L1=((2 1) (1 2) (0 1)), L2=((1 1) (0 1))
div-terms: L1=((1 1) (0 1)), L2=((1 1) (0 1))
div-terms: L1=(), L2=((1 1) (0 1))
Test12: Dividing x^2 + 2x + 1 by x+1: ((x (1 1) (0 1)) (x))
Test14: Adding polynomials of two variables: (polynomial x (1 1) (0 (polynomial y (1 1))))Test14: Adding polynomials of two variables, when one of them is nonexistant: (polynomial x (1 1) (0 (polynomial y (0 1))))zero-poly?: poly=(y (1 1))
zero-poly?: poly=(y (1 1))
Test25: multiplying different variables: (polynomial x (1 (polynomial y (1 1))))
Test 26: make-rational-polynomial: (rational (polynomial x (3 1) (0 1)) polynomial x (2 1) (0 1))
Test 27: add-rational
rational not droppable: #f
Test 27: (rational (polynomial x (5 2) (3 2) (2 2) (0 2)) polynomial x (4 1) (2 2) (0 1))
Test 28: polynomial-gcd: start
gcd-poly:p1=(x (4 1) (3 -1) (2 -2) (1 2)), p2=(x (3 1) (1 -1))
gcd-terms: a=((4 1) (3 -1) (2 -2) (1 2)), b=((3 1) (1 -1))
pseudoremainder-terms: P=((4 1) (3 -1) (2 -2) (1 2))
pseudoremainder-terms: Q=((3 1) (1 -1))
pseudoremainder-terms: O1=4
pseudoremainder-terms: O2=3
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((4 1) (3 -1) (2 -2) (1 2))
div-terms: L1=((4 1) (3 -1) (2 -2) (1 2)), L2=((3 1) (1 -1))
div-terms: L1=((3 -1) (2 -1) (1 2)), L2=((3 1) (1 -1))
div-terms: L1=((2 -1) (1 1)), L2=((3 1) (1 -1))
gcd-terms: a=((3 1) (1 -1)), b=((2 -1) (1 1))
pseudoremainder-terms: P=((3 1) (1 -1))
pseudoremainder-terms: Q=((2 -1) (1 1))
pseudoremainder-terms: O1=3
pseudoremainder-terms: O2=2
pseudoremainder-terms: c=-1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((3 1) (1 -1))
div-terms: L1=((3 1) (1 -1)), L2=((2 -1) (1 1))
div-terms: L1=((2 1) (1 -1)), L2=((2 -1) (1 1))
div-terms: L1=(), L2=((2 -1) (1 1))
gcd-terms: a=((2 -1) (1 1)), b=()
gcd-poly: unoptimized-termlist=((2 -1) (1 1))
gcd-poly: first-terms=((2 -1) (1 1))
gcd-poly: coefficients=(-1 1)
gcd-poly: coeff-gcd=1
Test 28: polynomial-gcd: (polynomial x (2 -1) (1 1))
Test 29: gcd-integer-problem: start
Test 29: p1=(polynomial x (2 1) (1 -2) (0 1))
Test 29: p2=(polynomial x (2 11) (0 7))
Test 29: p3=(polynomial x (1 13) (0 5))
Test 29: q1=(polynomial x (4 11) (3 -22) (2 18) (1 -14) (0 7))
Test 29: q2=(polynomial x (3 13) (2 -21) (1 3) (0 5))
gcd-poly:p1=(x (4 11) (3 -22) (2 18) (1 -14) (0 7)), p2=(x (3 13) (2 -21) (1 3) (0 5))
gcd-terms: a=((4 11) (3 -22) (2 18) (1 -14) (0 7)), b=((3 13) (2 -21) (1 3) (0 5))
pseudoremainder-terms: P=((4 11) (3 -22) (2 18) (1 -14) (0 7))
pseudoremainder-terms: Q=((3 13) (2 -21) (1 3) (0 5))
pseudoremainder-terms: O1=4
pseudoremainder-terms: O2=3
pseudoremainder-terms: c=13
pseudoremainder-terms: the integerizing factor=(0 169)
pseudoremainder-terms: P after multiplication=((4 1859) (3 -3718) (2 3042) (1 -2366) (0 1183))
div-terms: L1=((4 1859) (3 -3718) (2 3042) (1 -2366) (0 1183)), L2=((3 13) (2 -21) (1 3) (0 5))
div-terms: L1=((3 -715) (2 2613) (1 -3081) (0 1183)), L2=((3 13) (2 -21) (1 3) (0 5))
div-terms: L1=((2 1458) (1 -2916) (0 1458)), L2=((3 13) (2 -21) (1 3) (0 5))
gcd-terms: a=((3 13) (2 -21) (1 3) (0 5)), b=((2 1458) (1 -2916) (0 1458))
pseudoremainder-terms: P=((3 13) (2 -21) (1 3) (0 5))
pseudoremainder-terms: Q=((2 1458) (1 -2916) (0 1458))
pseudoremainder-terms: O1=3
pseudoremainder-terms: O2=2
pseudoremainder-terms: c=1458
pseudoremainder-terms: the integerizing factor=(0 2125764)
pseudoremainder-terms: P after multiplication=((3 27634932) (2 -44641044) (1 6377292) (0 10628820))
div-terms: L1=((3 27634932) (2 -44641044) (1 6377292) (0 10628820)), L2=((2 1458) (1 -2916) (0 1458))
div-terms: L1=((2 10628820) (1 -21257640) (0 10628820)), L2=((2 1458) (1 -2916) (0 1458))
div-terms: L1=(), L2=((2 1458) (1 -2916) (0 1458))
gcd-terms: a=((2 1458) (1 -2916) (0 1458)), b=()
gcd-poly: unoptimized-termlist=((2 1458) (1 -2916) (0 1458))
gcd-poly: first-terms=((2 1458) (1 -2916) (0 1458))
gcd-poly: coefficients=(1458 -2916 1458)
gcd-poly: coeff-gcd=1458
Test 29: gcd : (polynomial x (2 0.9999999999999999) (1 -1.9999999999999998) (0 0.9999999999999999))
#+end_example

We unfortunately, there is an error with exact-inexact numbers somewhere
here. I am too tired to fix it, but this should be doable. Let me say, I'd
also leave it as an exercise to the reader.

*** DONE Exercise 2.97 Reduction of polynomials
    CLOSED: [2019-10-29 Tue 00:12]

Here is the solution of the exercise. I have to copy the code again, because
implementing term reduction requires extending the polynomial package.

#+begin_src scheme :exports both :results output
	  (define (thingy-source thingy)
	    (cond ((lambda? thingy) (list "lambda" (lambda-source thingy)))
		  ((procedure? thingy) (list "procedure" (procedure-name thingy)))
		  ((pair? thingy) (list "pair" (pair-source thingy)))
		  (else "No source? refactor")))

	    (define (accumulate op initial sequence)
	      (if (null? sequence)
		  initial
		  (accumulate op (op initial (car sequence)) (cdr sequence))))
	    (define false #f)
	    (define true  #t)
	    (define (make-table)
	      (let ((local-table (list '*table*)))
		(define (lookup key-1 key-2)
		  (let ((subtable (assoc key-1 (cdr local-table))))
		    (if subtable
			(let ((record (assoc key-2 (cdr subtable))))
			  (if record
			      (cdr record)
			      false))
			false)))
		(define (insert! key-1 key-2 value)
		  (let ((subtable (assoc key-1 (cdr local-table))))
		    (if subtable
			(let ((record (assoc key-2 (cdr subtable))))
			  (if record
			      (set-cdr! record value)
			      (set-cdr! subtable
					(cons (cons key-2 value)
					      (cdr subtable)))))
			(set-cdr! local-table
				  (cons (list key-1
					      (cons key-2 value))
					(cdr local-table)))))
		  'ok)
		(define (dispatch m)
		  (cond ((eq? m 'lookup-proc) lookup)
			((eq? m 'insert-proc!) insert!)
			(else (error "Unknown operation -- TABLE" m))))
		dispatch))

	    (define operation-table (make-table))
	    (define get (operation-table 'lookup-proc))
	    (define put (operation-table 'insert-proc!))

	    (define coercion-table (make-table))
	    (define get-coercion (coercion-table 'lookup-proc))
	    (define put-coercion (coercion-table 'insert-proc!))

	    (define (attach-tag type-tag contents)
	      (cons type-tag contents))

	    (define (type-tag datum)
	      (cond ((pair? datum) (car datum))
		    ((exact-integer? datum) 'integer)
		    ((real? datum) 'scheme-number)
		    (error "Bad tagged datum -- TYPE-TAG" datum)))

	  (define (contents datum)
	      (cond ((pair? datum) (cdr datum))
		    ((integer? datum) datum)
		    ((real? datum) datum)
		    (else (error "Bad tagged datum -- CONTENTS" datum))))

	    (define (integer? x)
	      (eq? (type-tag x) 'integer))
	    (define (rectangular? z)
	      (eq? (type-tag z) 'rectangular))

	    (define (polar? z)
	      (eq? (type-tag z) 'polar))


	    (define (real-part z) (apply-generic 'real-part z))
	    (define (imag-part z) (apply-generic 'imag-part z))
	    (define (magnitude z) (apply-generic 'magnitude z))
	    (define (angle z) (apply-generic 'angle z))

	    (define (add x y) 
	       #;(show #t "debug:add: x=" x ", y=" y ", starting apply-generic\n")
	       #;(show #t "debug:add: (type-tags x,y)=(" (type-tag x) "," (type-tag y) ")" "\n")
	       #;(show #t "debug:add:can we access apply-generic?" (written apply-generic)
			"\n" )
	       #;(error "Debug1")
	       (apply-generic 'add x y))
	    (define (sub x y) (apply-generic 'sub x y))
	    (define (mul x y) (apply-generic 'mul x y))
	    (define (div x y) (apply-generic 'div x y))

	    (define (equ? x y)
	      (apply-generic 'equ? x y))
	    (define (zero? x) (apply-generic 'zero? x))

	    (define (exp x y) (apply-generic 'exp x y))

	    (define (install-scheme-number-package)
	      (define (tag x)
		#;(attach-tag 'scheme-number x) x)
	      (show #t "(tag 5)=" (tag 5) "\n")
	      (put 'add '(scheme-number scheme-number)
		   (lambda (x y) #;(show #t "debug:found plus dispatch\n") (tag (+ x y))))
	      (put 'sub '(scheme-number scheme-number)
		   (lambda (x y) (tag (- x y))))
	      (put 'mul '(scheme-number scheme-number)
		   (lambda (x y) (tag (* x y))))
	      (put 'div '(scheme-number scheme-number)
		   (lambda (x y) (tag (/ x y))))
	      (put 'make 'scheme-number
		   (lambda (x) #;(show #t "debug:found 'make 'scheme-number\n") (tag x)))
	      (put 'equ? '(scheme-number scheme-number)
		   (lambda (x y) (= x y)))
	      (put 'zero? '(scheme-number)
		   (lambda (x) (= 0 x)))
	      (put 'exp '(scheme-number scheme-number)
		   (lambda (x y) (tag (expt x y))))
	      (put 'project '(scheme-number)
		   (lambda (x)
		     (if (finite? x)
			(exact (truncate x))
			0)))
	      (put 'sine '(scheme-number) sin)
	      (put 'cosine '(scheme-number) cos)
	      (put 'square-root '(scheme-number) sqrt)
	      (put 'arctangent '(schemer-number) atan)
	      'done)
    (install-scheme-number-package)
	  (define (integer->scheme-number x)
	     (make-scheme-number (inexact (contents x))))
	  (put-coercion 'integer 'scheme-number integer->scheme-number)  

	    (define (sine x) (apply-generic 'sine x))
	    (define (cosine x) (apply-generic 'cosine x))
	    (define (square-root x) (apply-generic 'square-root x))
	    (define (arctangent x) (apply-generic 'arctangent x))

	    (define (make-scheme-number n)
	       #;(show #t "debug:make-scheme-number: n=" n "\n")
	      ((get 'make 'scheme-number) n))
	    #;(check (+ 1 1) => 2)
	    (show #t "Test 31: start\n")
	    (show #t "Test 31:" (equal? (make-scheme-number 1) 1) "\n")

	    #;(check (add (make-scheme-number 1) (make-scheme-number 1)) => 2)

	    (define (install-rational-package)
	      (define (numer x) (car x))
	      (define (denom x) (cdr x))
	      (define (make-rat n d)
		(show #t "make-rat: n=" n ", d="d "\n")
		#;(let ((g (gcd n d)))
		  (cons (/ n g) (/ d g)))
		  (let ((new-list (reduce n d)))
		     (cons (car new-list) (cadr new-list))))
	      (define (add-rat x y)
		(make-rat (add (mul (numer x) (denom y))
			     (mul (numer y) (denom x)))
			  (mul (denom x) (denom y))))
	      (define (sub-rat x y)
		(make-rat (sub (mul (numer x) (denom y))
			     (mul (numer y) (denom x)))
			  (mul (denom x) (denom y))))
	      (define (mul-rat x y)
		(make-rat (mul (numer x) (numer y))
			  (mul (denom x) (denom y))))
	      (define (div-rat x y)
		(make-rat (mul (numer x) (denom y))
			  (mul (denom x) (numer y))))

	      (define (tag x) (attach-tag 'rational x))
	      (put 'add '(rational rational)
		   (lambda (x y) (tag (add-rat x y))))
	      (put 'sub '(rational rational)
		   (lambda (x y) (tag (sub-rat x y))))
	      (put 'mul '(rational rational)
		   (lambda (x y) (tag (mul-rat x y))))
	      (put 'div '(rational rational)
		   (lambda (x y) (tag (div-rat x y))))

	      (put 'make 'rational
		   (lambda (n d) (tag (make-rat n d))))
	      (put 'equ? '(rational rational)
		   (lambda (x y) (zero? (numer (sub-rat x y)))))
	      (put 'zero? '(rational) (lambda (x) (zero? (numer x))))
	      #;(put 'project '(rational) (lambda (x) 
					  (exact (truncate (/ (numer x) (denom x))))))
	      #;(put 'to-real '(rational) (lambda (x) (/ (numer (contents x)) (denom (contents x)))))
	      'done)

	    (define (make-rational n d)
	      ((get 'make 'rational) n d))

	    (define (install-rectangular-package)

	      (define (real-part z) (car z))
	      (define (imag-part z) (cdr z))
	      (define (make-from-real-imag x y) (cons x y))
	      (define (magnitude z)
		(square-root (add (square (real-part z))
				  (square (imag-part z)))))
	      (define (angle z)
		(arctangent (imag-part z) (real-part z)))
	      (define (make-from-mag-ang r a)
		(cons (mul r (cosine a)) (mul r (sine a))))

	      (define (tag x) (attach-tag 'rectangular x))
	      (put 'real-part '(rectangular) real-part)
	      (put 'imag-part '(rectangular) imag-part)
	      (put 'magnitude '(rectangular) magnitude)
	      (put 'angle '(rectangular) angle)
	      (put 'make-from-real-imag 'rectangular
		   (lambda (x y) (tag (make-from-real-imag x y))))
	      (put 'make-from-mag-ang 'rectangular
		   (lambda (r a) (tag (make-from-mag-ang r a))))
	      'done)

	    (define (install-polar-package)

	      (define (magnitude z) (car z))
	      (define (angle z) (cdr z))
	      (define (make-from-mag-ang r a) (cons r a))
	      (define (real-part z)
		(mul (magnitude z) (cosine (angle z))))
	      (define (imag-part z)
		(mul (magnitude z) (sine (angle z))))
	      (define (make-from-real-imag x y)
		(cons (square-root (add (square x) (square y)))
		      (arctangent y x)))

	      (define (tag x) (attach-tag 'polar x))
	      (put 'real-part '(polar) real-part)
	      (put 'imag-part '(polar) imag-part)
	      (put 'magnitude '(polar) magnitude)
	      (put 'angle '(polar) angle)
	      (put 'make-from-real-imag 'polar
		   (lambda (x y) (tag (make-from-real-imag x y))))
	      (put 'make-from-mag-ang 'polar
		   (lambda (r a) (tag (make-from-mag-ang r a))))
	      'done)

	    (define (install-complex-package)
	      (define (make-from-real-imag x y)
		((get 'make-from-real-imag 'rectangular) x y))
	      (define (make-from-mag-ang r a)
		((get 'make-from-mag-ang 'polar) r a))
	      (define (add-complex z1 z2)
		(make-from-real-imag (add (real-part z1) (real-part z2))
				     (add (imag-part z1) (imag-part z2))))
	      (define (sub-complex z1 z2)
		(make-from-real-imag (sub (real-part z1) (real-part z2))
				     (sub (imag-part z1) (imag-part z2))))
	      (define (mul-complex z1 z2)
		(make-from-mag-ang (mul (magnitude z1) (magnitude z2))
				   (add (angle z1) (angle z2))))
	      (define (div-complex z1 z2)
		(make-from-mag-ang (div (magnitude z1) (magnitude z2))
				   (sub (angle z1) (angle z2))))
	      (define (tag z) (attach-tag 'complex z))
	      (put 'add '(complex complex)
		   (lambda (z1 z2) (tag (add-complex z1 z2))))
	      (put 'sub '(complex complex)
		   (lambda (z1 z2) (tag (sub-complex z1 z2))))
	      (put 'mul '(complex complex)
		   (lambda (z1 z2) (tag (mul-complex z1 z2))))
	      (put 'div '(complex complex)
		   (lambda (z1 z2) (tag (div-complex z1 z2))))
	      (put 'make-from-real-imag 'complex
		   (lambda (x y) (tag (make-from-real-imag x y))))
	      (put 'make-from-mag-ang 'complex
		   (lambda (r a) (tag (make-from-mag-ang r a))))
	      (put 'equ? '(complex complex)
		   (lambda (x y) (and (= 0 (real-part (sub-complex x y)))
				      (= 0 (imag-part (sub-complex x y))))))
	      (put 'equ? '(rectangular polar) equ?)
	      (put 'equ? '(polar rectangular) equ?)
	      (put 'zero? '(complex)
		   (lambda (x) (equ? (tag x) (tag (make-from-real-imag 0 0)))))
	      (put 'project '(complex) (lambda (z) (real-part z)))
	      'done)

	    (define (make-complex-from-real-imag x y)
	      ((get 'make-from-real-imag 'complex) x y))

	    (define (make-complex-from-mag-ang r a)
	      ((get 'make-from-mag-ang 'complex) r a))

	    (install-rectangular-package)
	    (install-polar-package)
	    (install-rational-package)

	    (install-complex-package)

	    (put 'real-part '(complex) real-part)
	    (put 'imag-part '(complex) imag-part)
	    (put 'magnitude '(complex) magnitude)
	    (put 'angle '(complex) angle)
	    (define (polynomial? x)
	      (eq? (type-tag x) 'polynomial))
	    (define numeric-tower (list 'integer 'scheme-number 'complex))
	    (define (numeric? x)
	      (memq x numeric-tower))
	    (define (type1<=type2? type1 type2)
	      (if (not (memq type1 numeric-tower))
		  (error "Type 1 not in the numeric tower"))
	      (if (not (memq type2 numeric-tower))
		  (error "Type 2 not in the numeric tower"))
	      (let loop ((types numeric-tower))
		(cond ((null? types) (error "Type 1 and type 2 are incomparable" type1 type2))
		      ((eq? (car types) type1) #t)
		      ((eq? (car types) type2) #f)
		      (else (loop (cdr types))))))
	    (define (comparable? type1 type2) 
	      (and (memq type1 numeric-tower) 
		  (memq type2 numeric-tower)))
	    (define (raise-type x)
	    #;(show #t "Raising type of: " (displayed x) "\n")
	      (let ((converter (get-coercion (type-tag x) (higher-type (type-tag x)))))
		(if converter
		    (converter x)
		    (error "No coercion found for x" (type-tag x) x))))
	  (define (higher-type x)
	    (let ((tail (memq x numeric-tower)))
	      (cond ((eq? #f tail) (error "Type not in the tower" x))
		    ((null? (cdr tail)) (error "Already the highest type:" x))
		    (else (cadr tail)))))

	  (show #t "Test: Higher than 'integer: " (higher-type 'integer) "\n")
	    (define (remainder-integer a b)
	      (when (or (not (integer? a)) (not (integer? b)))
		(error "Arguments must be integers" a b))
	      (remainder a b))

	    (put 'remainder '(integer integer) remainder-integer)
	    (define (remainder-generalized a b) (apply-generic 'remainder a b))

	    (define (project obj)
	      (apply-generic 'project obj))
	    (define (droppable? obj)
	      #;(show #t "droppable?: obj=" obj ", type-tag=" (type-tag obj) "\n")
	      (cond ((eq? (type-tag obj) 'rational) (begin (show #t "rational not droppable: #f\n") #f))
		    ((not (memq (type-tag obj) numeric-tower)) #f)
		    ((eq? (type-tag obj) (car numeric-tower)) #f)
		    ((equ? obj (raise-type (project obj))) #t)
		    (else #f)))
	    (define (drop obj) 
	      (if (droppable? obj)
		  (drop (project obj))
		  obj))

	    (define (apply-generic op . args)
	      #;(show #t "apply-generic:entry\n")
	      #;(error "debug")
	      (define (variable poly) (car poly))
	      (define (all-argtypes-same? . args)
		(let ((type (type-tag (car args))))
		  (accumulate (lambda (x y) (and x y)) #t (map (lambda (x) (eq? type x)) args))))
	      (define (coercion-if-exists? type arg-tags)
		(let ((coercion-list (map (lambda (x) 
					    (if (eq? type x)
						identity
						(get-coercion x type))) arg-tags)))
		  (if (accumulate (lambda (x y) (and x y)) #t coercion-list)
		      coercion-list
		      #f)))
	      (drop (let* ((type-tags (map type-tag args))
			   (proc (get op type-tags)))
		     #;(show #t "apply-generic: type-tags=" 
			       (displayed type-tags)
			       " proc=" (written proc)
			       " proc-source=" (thingy-source proc) "\n")
		      (cond (proc (apply proc (map contents args)))
			    ((= 1 (length args))
		     #;(show #t "No proc found for op=" op ", type-tags=" type-tags ", arg=" (displayed args) "\n")
			     (apply-generic op (raise-type (car args))))
			    ((= 2 (length args))
			     (cond ((and (eq? 'polynomial (car type-tags))
				       (numeric? (cadr type-tags)))
				    (apply-generic op
						   (car args)
						   (make-polynomial (variable (contents (car args)))
								    (list (list 0 (cadr args))))))
				   ((and (numeric? (car type-tags))
				 (eq? 'polynomial (cadr type-tags)))
				    (apply-generic op
						   (make-polynomial (variable (contents (cadr args)))
								    (list (list 0 (car args))))
						   (cadr args)))			 
				   ((and (get-coercion (car type-tags) (cadr type-tags))
				       (not (eq? (car type-tags) (cadr type-tags))))
				    (apply-generic op
						   ((get-coercion
						     (car type-tags)
						     (cadr type-tags)) (car args))
						   (cadr args)))
				   ((and (get-coercion (cadr type-tags) (car type-tags))
				       (not (eq? (car type-tags) (cadr type-tags))))
				    (apply-generic op
						   (car args)
						   ((get-coercion
						     (cadr type-tags)
						     (car type-tags)) (cadr args) )))
				   ((comparable? (car type-tags) (cadr type-tags))
				    (if
				     (type1<=type2? (car type-tags) (cadr type-tags))
				     (apply-generic op (raise-type (car args)) (cadr args))
				     (apply-generic op (car args)  (raise-type (cadr args)))))
				   (else (error "apply-generic:Incomparable types: (type-tags,args)=" type-tags args))))
			    ((and (> (length args) 2) (not (all-argtypes-same? args)))
			     (let types-loop ((types type-tags))
			       (let ((list-of-coercion-functions
				      (coercion-if-exists? (car types) type-tags)))
				 (if list-of-coercion-functions
				     (apply apply-generic (cons op (map (lambda (fun arg) (fun arg))
									list-of-coercion-functions
									args)))
				     (if (not (null? (cdr types)))
					 (types-loop (cdr types))
					 (error "apply-generic:Even coercions failed. No method for these types."))))))
			    (else (error "apply-generic:No method for these types"
					 (list op type-tags)))))))
	    (show #t "Test 30: start\n")
	    (show #t "Test 30:(add (make-scheme-number 1) (make-scheme-number 1))= "
	       (add (make-scheme-number 1) (make-scheme-number 1)) "\n")
	    #;(error "Debug6")
	    (define (scheme-number->complex n)
	      (make-complex-from-real-imag (contents n) 0))
	    (put-coercion 'scheme-number
			  'complex
			  scheme-number->complex)

	    (show #t "Test 32: start")
	    (show #t "Test 32: Subtracting complex numbers: "
		  (sub
		   (make-complex-from-real-imag 1.1 2)
		   (make-complex-from-real-imag 0 2)) "\n")



	    (put 'max3-magnitude '(complex complex complex) (lambda (z1 z2 z3)
							      (max (magnitude z1) (magnitude z2) (magnitude z3))))
	    (define (max3-magnitude x1 x2 x3) (apply-generic 'max3-magnitude x1 x2 x3))
	    (define (identity x) x)

	  #;(define numeric-tower (list 'integer 'rational 'scheme-number 'complex))


	  #;(define (higher-type x)
	    (show #t "higher-type:x=" (displayed x) "\n")
	      (define (find-higher-type x types)
		(cond ((or (null? types) (null? (cdr types))) (error "No type higher than given" x types))
		      ((eq? x (car types)) (cadr types))
		      (else (find-higher-type x (cdr types)))))
	      (find-higher-type x numeric-tower))

	  #;(show #t "Test: Higher than 'complex: " (higher-type 'complex) "\n")

	    #;(define (integer->rational x)
	      (make-rational x 1))

	    #;(define (rational->scheme-number x)
	      (make-scheme-number ((get 'to-real '(rational)) x)))
	    #;(put-coercion 'integer 'rational integer->rational)
	    #;(put-coercion 'rational 'scheme-number rational->scheme-number)
	      (define (reduce-integers n d)
		   (let ((g (gcd n d)))
		     (list (/ n g) (/ d g))))
	  (put 'reduce '(integer integer) reduce-integers)
	  (define (reduce a b) (apply-generic 'reduce a b))
	  (define (install-polynomial-package)
	    #;(define (contents generic-object)
	      (cdr generic-object))
	      (define (make-poly variable term-list)
		(cons variable term-list))
	      (define (variable p) (car p))
	      (define (term-list p)
		(cdr p))
	      (define (variable? x) (symbol? x))
	      (define (same-variable? v1 v2)
		(and (variable? v1) (variable? v2) (eq? v1 v2)))
	      (define (=number? exp num)
		(and (number? exp) (= exp num)))
	      (define (the-empty-termlist) '())

	      (define (rest-terms term-list) (cdr term-list))
	      (define (empty-termlist? term-list) (null? term-list))

	      (define (make-term order coeff) (list order coeff))
	      (define (order term) (car term))
	      (define (coeff term) (cadr term))
	      (define (tag p) (attach-tag 'polynomial p))
	      (put 'make 'polynomial
		   (lambda (var terms) (tag (make-poly var terms))))
	      #;(continued on next page)

	      (define (add-poly p1 p2)
		#;(show #t "add-poly: p1=" p1 ", p2=" p2 "\n")
		(if (same-variable? (variable p1) (variable p2))
		    (make-poly (variable p1)
			       (add-terms (term-list p1)
					  (term-list p2)))
		    (let ((res (cdr (if (variable_1-order<variable_2-order (variable p1) (variable p2))
			(add (tag p1) (tag (make-poly (variable p1) (list (make-term 0 (tag p2))))))
			(add (tag (make-poly (variable p2) (list (make-term 0 (tag p1))))) (tag p2))))))
		      #;(show #t "add-poly:result: " (displayed res) "\n") res)))

	      (show #t "TestY2: poly of poly: "
		    (make-poly 'x (list
				   (make-term 3 (make-poly
						 'y (list (make-term 1 1) (make-term 0 1))))
				   (make-term 1 2)
				   (make-term 0 4))) "\n")

	      (define (sub-poly p1 p2)
		(add-poly p1 (mul-poly p2 (make-poly (variable p2) (list (make-term 0 -1))))))
	      (define (add-terms L1 L2)
		(cond ((empty-termlist? L1) L2)
		      ((empty-termlist? L2) L1)
		      (else
		       (let ((t1 (first-term L1)) (t2 (first-term L2)))
			 (cond ((> (order t1) (order t2))
				(adjoin-term
				 t1 (add-terms (rest-terms L1) L2)))
			       ((< (order t1) (order t2))
				(adjoin-term
				 t2 (add-terms L1 (rest-terms L2))))
			       (else
				(adjoin-term
				 (make-term (order t1)
					    (add (coeff t1) (coeff t2)))
				 (add-terms (rest-terms L1)
					    (rest-terms L2)))))))))


	      (define (mul-poly p1 p2)
		(if (same-variable? (variable p1) (variable p2))
		    (make-poly (variable p1)
			       (mul-terms (term-list p1)
					  (term-list p2)))
		    (contents (if (variable_1-order<variable_2-order (variable p1) (variable p2))
			(mul (tag p1)
			     (make-polynomial (variable p1)
					      (adjoin-term
					       (make-term 0
							  (tag p2)) (the-empty-termlist))))
			(mul (tag p2)
			     (make-polynomial (variable p2)
					      (adjoin-term
					       (make-term 0
							  (tag p1)) (the-empty-termlist))))))
		    #;(error "Polys not in same var -- MUL-POLY"
			   (list p1 p2))))
	      (define (div-poly p1 p2)
		(show #t "div-poly: p1=" p1 ", p2=" p2 "\n")
		(if (same-variable? (variable p1) (variable p2))
		    (let ((quotient-and-remainder (div-terms (term-list p1)
							     (term-list p2))))
		      (list (make-poly (variable p1) (car  quotient-and-remainder))
			    (make-poly (variable p1) (cadr quotient-and-remainder))))
		      (error "div-poly: Polys not in the same var" p1 p2)))
	      (define (div-terms L1 L2)
		      (show #t "div-terms: L1=" L1 ", L2=" L2 "\n")
		      (if (empty-termlist? L1)
			  (list (the-empty-termlist) (the-empty-termlist))
			  (let ((t1 (first-term L1))
				(t2 (first-term L2)))
			    (if (> (order t2) (order t1))
				(list (the-empty-termlist) L1)
				(let ((new-c (div (coeff t1) (coeff t2)))
				      (new-o (- (order t1) (order t2))))
				  (let ((rest-of-result (div-terms (term-list
								    (sub-poly
								     (make-poly 'fake-var L1)
								     (mul-poly
								      (make-poly 'fake-var (list (make-term new-o new-c)))
								      (make-poly 'fake-var L2))))
								   L2)
							))
				    #;(show #t "div-terms: rest-of-result: " (displayed rest-of-result) "\n")
				    (list (adjoin-term (make-term new-o new-c) (car rest-of-result)) (cadr rest-of-result))
				    ))))))
	      (define (gcd-terms a b)
	      (show #t "gcd-terms: a=" a ", b=" b "\n")
		(if (empty-termlist? b)
		    a
		    (gcd-terms b (pseudoremainder-terms a b))))
	      (define (pseudoremainder-terms P Q)
		(let ((O1 (order (first-term P)))
		      (O2 (order (first-term Q)))
		      (c  (coeff (first-term Q))))
		   (show #t "pseudoremainder-terms: P=" P "\n")
		   (show #t "pseudoremainder-terms: Q=" Q "\n")
		   (show #t "pseudoremainder-terms: O1=" O1 "\n")
		   (show #t "pseudoremainder-terms: O2=" O2 "\n")
		   (show #t "pseudoremainder-terms: c=" c "\n")

		   (show #t "pseudoremainder-terms: the integerizing factor="
		      (make-term 0 (exp c (add 1 (sub O1 O2)))) "\n" )
		   (show #t "pseudoremainder-terms: P after multiplication="
		     (mul-term-by-all-terms 
					 (make-term 0 (exp c (add 1 (sub O1 O2)))) P)  "\n" )
		   (cadr (div-terms (mul-term-by-all-terms 
					 (make-term 0 (exp c (add 1 (sub O1 O2)))) P) Q))))
		(define (maprest operation term-list)
		(show #t "maprest: operation=" (written operation) "term-list=" term-list "\n" )
		     (if (empty-termlist? term-list)
			 '()
			 (cons (operation term-list) (maprest operation (rest-terms term-list))))
		)
		(define (gcd-poly p1 p2)
		(show #t "gcd-poly:p1=" p1 ", p2=" p2 "\n") 

		(if (same-variable? (variable p1) (variable p2))
		    (let* ((unoptimized-termlist (gcd-terms (term-list p1) (term-list p2)))
			   (first-terms (maprest first-term unoptimized-termlist))
			  (coefficients (map coeff first-terms))
			  (coeff-gcd (apply gcd coefficients))
			  (optimized-termlist (mul-term-by-all-terms 
					 (make-term 0 (div 1 coeff-gcd)) unoptimized-termlist)))
		       (show #t "gcd-poly: unoptimized-termlist=" unoptimized-termlist "\n")
		       (show #t "gcd-poly: first-terms=" first-terms "\n")
		       (show #t "gcd-poly: coefficients=" coefficients "\n")
		       (show #t "gcd-poly: coeff-gcd=" coeff-gcd "\n")
		       (make-poly (variable p1) optimized-termlist))
		    (error "div-poly: Polys not in the same var" p1 p2)))
	      (put 'gcd '(polynomial polynomial)
		   (lambda (x y) (tag (gcd-poly x y))))
	      (put 'gcd '(integer integer) gcd)

	      (define (mul-terms L1 L2)
		(if (empty-termlist? L1)
		    (the-empty-termlist)
		    (add-terms (mul-term-by-all-terms (first-term L1) L2)
			       (mul-terms (rest-terms L1) L2))))

	      (define (mul-term-by-all-terms t1 L)
		(if (empty-termlist? L)
		    (the-empty-termlist)
		    (let ((t2 (first-term L)))
		      (adjoin-term
		       (make-term (+ (order t1) (order t2))
				  (mul (coeff t1) (coeff t2)))
		       (mul-term-by-all-terms t1 (rest-terms L))))))

	      (define (reduce-terms termlist-1 termlist-2)
		(show #t "reduce-terms: termlist-1=" termlist-1
				     ", termlist-2=" termlist-2 "\n")
		(let* ((poly-gcd (gcd-terms termlist-1 termlist-2))
		      (O1 (max (order (first-term termlist-1))
                               (order (first-term termlist-2))))
		      (O2 (order (first-term poly-gcd)))
		      (c  (coeff (first-term poly-gcd)))
		      (int-factor (exp c (+ 1 (- O1 O2))))
		      (int-term (make-term 0 int-factor)) 
		      (impr-termlist-1 (mul-term-by-all-terms int-term termlist-1))
		      (impr-termlist-2 (mul-term-by-all-terms int-term termlist-2))
		      (new-t1 (car (div-terms impr-termlist-1 poly-gcd)))
		      (new-t2 (car (div-terms impr-termlist-2 poly-gcd)))
		      (new-t1-terms (map coeff (maprest first-term new-t1)))
		      (new-t2-terms (map coeff (maprest first-term new-t2)))
		      (full-list (append new-t1-terms new-t2-terms))
		      (new-gcd (begin (show #t "full-list=" full-list "\n")
                                      (apply gcd full-list)))
		      (divisor-term (make-term 0 (div 1 new-gcd)))
		      (new-t1-impr (mul-term-by-all-terms divisor-term new-t1))
		      (new-t2-impr (mul-term-by-all-terms divisor-term new-t2)))
		  (list new-t1-impr new-t2-impr)))
	      (define (reduce-poly p1 p2)
		(show #t "reduce-poly: p1=" p1 ", p2=" p2 "\n")
		(if (same-variable? (variable p1) (variable p2))
		    (let* ((num-den-list (reduce-terms (term-list p1) (term-list p2)))
			   (my-var (variable p1))
			   (new-p1 (make-poly my-var (car num-den-list)))
			   (new-p2 (make-poly my-var (cadr num-den-list))))
			(list (tag new-p1) (tag new-p2)))
		    (error "reduce-poly: different variables")))
	      (put 'reduce '(polynomial polynomial) reduce-poly)
	      (define (zero-poly? poly)
		(show #t "zero-poly?: poly=" (displayed poly) "\n")
		(cond ((empty-termlist? (term-list poly)) #t)
		      ((not (zero? (coeff (first-term (term-list poly))))) #f)
		      (else (zero-poly? 
			     (make-poly (variable poly)
					(rest-terms (term-list poly)))))))

	      (define (termlist-type-of term-list)
		#;(show #t "t-t-o: term-list=" (displayed term-list) "\n")
		(cond ((null? term-list) 'sparse)
		      ((pair? (car term-list)) 'sparse)
		      ((list? term-list) 'dense)
		      (else (error "Unknown type of list" term-list))))
	      (define (adjoin-term term term-list)
		((get 'adjoin-term (termlist-type-of term-list)) term term-list))
	      (define (first-term term-list)
		((get 'first-term (termlist-type-of term-list)) term-list))
	      (define (variable_1-order<variable_2-order variable_1 variable_2)
		#;(show #t "var_1-..: variable_1=" variable_1 " variable_2=" variable_2 "\n")
		#;(show #t "var12string=" (symbol->string variable_1) "var22string=" (symbol->string variable_2) "\n")
		(string<=? (symbol->string variable_1) (symbol->string variable_2)))
	      (define (normalize-fully poly)
		(if (normal-polynomial? poly)
		    poly
		    (normalize-fully (normalize-once poly))))
	      (put 'add '(polynomial polynomial)
		   (lambda (p1 p2) 
		     #;(show #t "generic-add-poly:Polynomial dispatch found: p1="
			    (displayed p1) " p2=" (displayed p2) "\n")
		     (normalize-fully (tag (add-poly p1 p2)))))
	      (put 'mul '(polynomial polynomial)
		   (lambda (p1 p2) (normalize-fully (tag (mul-poly p1 p2)))))
	      (put 'sub '(polynomial polynomial)
		   (lambda (p1 p2) (tag (sub-poly p1 p2))))

	      (put 'zero? '(polynomial) zero-poly?)
	      (put 'div '(polynomial polynomial) div-poly)
	      #;(put-coercion 'rational 'scheme-number rational->scheme-number)
	      (define (monomial-flip-variables monomial)
		#;(show #t "m-f-v: monomial=" monomial "\n")
		(let* ((mono (contents monomial))
		       (inner-polynomial (contents (coeff (first-term (term-list mono)))))
		       (inner-poly (contents inner-polynomial))
		       (outer-order (order (first-term (term-list mono))))
		       (outer-var (variable mono))
		       (inner-var (variable inner-polynomial))
		       (inner-term-list (term-list inner-poly)))
		  #;(show #t "m-f-v: inner-poly=" inner-poly "\n")
		  (if (same-variable? inner-var outer-var)
		      (mul
		       (make-polynomial outer-var (adjoin-term (make-term outer-order 1) (the-empty-termlist)))
		       (tag inner-polynomial))
		      (tag (make-poly inner-var
				      (mul-term-by-all-terms (make-term
							      0
							      (make-polynomial
							       outer-var
							       (list (make-term
								      outer-order
								      1)))) inner-poly))))))
	      #;(show #t "TestXX: sorting variables: Is 'x < 'y?: "
		    (variable_1-order<variable_2-order 'x 'y) "\n")
	      #;(show #t "TestXX: sorting variables: Is 'z < 'y?: "
		    (variable_1-order<variable_2-order 'z 'y) "\n")
	      #;(show #t "TestXX: (adding two basic poly): "
		    (add (make-polynomial 'x (list (make-term 1 2) (make-term 0 4)))
			 (make-polynomial 'y (list (make-term 2 3) (make-term 0 5)))) "\n")

	      (define (polynomial->sum-of-first-and-rest poly)
		#;(show #t "p->s-o-f-a-r: " (displayed poly) "\n")
		(if (zero? poly)
		    poly
		    (let* ((poly1 (contents poly))
			   (first-monomial (tag
					    (make-poly
					     (variable poly1)
					     (list (first-term (term-list poly1)))))))
		      #;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		      (add
			first-monomial
			(polynomial->sum-of-first-and-rest
			 (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	      (show #t "Test13: Expanding a polynomial as monomials: "
		    (displayed
		     (polynomial->sum-of-first-and-rest
		      (make-polynomial 'y
				       (list (make-term 2 (make-polynomial
							   'x
							   (list (make-term 2 1) (make-term 0 1))))
					     (make-term 0 2))))) "\n")

	      (show #t "\nTest20: start monomial: "
		    (displayed (make-polynomial 'x
						(list
						 (make-term
						  2
						  (make-polynomial
						   'y
						   (list
						    (make-term 2 1) (make-term 0 1))))))) "\n")
	      (show #t "Test20: Flipping a monomial variable: "
		    (displayed
		     (monomial-flip-variables
		      (make-polynomial 'x
				       (list (make-term 1 (make-polynomial
							   'y
							   (list
							    (make-term 2 1)
							    (make-term 0 1)))))))) "\n\n")


	      (define (normal-polynomial? poly)
		#;(show #t "n-p?: poly=" poly "\n")
		(cond ((not (polynomial? poly)) #t)
		      ((null? (term-list (contents poly))) #t)
		      (else (let* ((poly1 (contents poly))
				   (outer-var (variable poly1)))
			      #;(show #t "Inner-let: outer-var=" (displayed outer-var) "\n")
			      (let loop ((terms (term-list poly1)))
				#;(show #t "n-p?-loop: terms=" (displayed terms) "\n")
				(cond ((null? terms) #t)
				      ((not (polynomial? (coeff (first-term terms)))) (loop (rest-terms terms)))
				      ((not (variable_1-order<variable_2-order 
					   outer-var
					   (variable (contents (coeff (first-term terms)))))) (begin #;(show #t "wrong variable order \n") #f))
				      ((not (normal-polynomial? (coeff (first-term terms)))) (begin #;(show #t "not normal poly\n") #f))
				      (else (loop (rest-terms terms)))))
			      ))))
	      (define (normalize-once poly)
		#;(show #t "normalize-once poly= " (displayed poly) "\n")
		(if (zero? poly)
		    poly
		    (let* ((poly1 (contents poly))
			   (first-monomial (tag
					    (make-poly
					     (variable poly1)
					     (list (make-term
						    (order (first-term (term-list poly1)))
						    (if (polynomial? (coeff (first-term (term-list poly1))))
							(normalize-once (coeff (first-term (term-list poly1))))
							(coeff (first-term (term-list poly1))))))))))
		      #;(show #t "p->s-o-f-a-r: " (displayed first-monomial) "\n")
		      (add
		       (if (and (polynomial?
			       (coeff
				(first-term
				 (term-list
				  (contents first-monomial)))))
			      (variable_1-order<variable_2-order
			       (variable
				(contents
				 (coeff
				  (first-term
				   (term-list
				    (contents first-monomial))))))
			       (variable
				(contents first-monomial))))
			   (monomial-flip-variables first-monomial)
			   first-monomial)
			(polynomial->sum-of-first-and-rest
			 (tag (make-poly (variable poly1) (rest-terms (term-list poly1)))))))))

	      (show #t "Test21: normal-polynomial?:start: " (displayed (make-polynomial 'y
						     (list (make-term 2 (make-polynomial
									 'x
							   (list (make-term 2 1) (make-term 0 1))))
							   (make-term 0 2)))) "\n")
	      #;(show #t "Test21: normal-polynomial?:result:" (normal-polynomial? (make-polynomial 'y
						     (list (make-term 2 (make-polynomial
									 'x
							   (list (make-term 2 1) (make-term 0 1))))
							   (make-term 0 2)))) "\n")
	      #;(show #t "Test22: normal-polynomial?-good:start: "
		    (displayed
		     (make-polynomial 'x
				      (list (make-term 2 (make-polynomial
							  'y
							  (list (make-term 2 1) (make-term 0 1))))
					    (make-term 0 2)))) "\n")
	      #;(show #t "Test22: normal-polynomial?-good:result:"
		    (normal-polynomial?
		     (make-polynomial 'x
				      (list (make-term 2 (make-polynomial
							  'y
							  (list (make-term 2 1) (make-term 0 1))))
					    (make-term 0 2)))) "\n")

	      #;(show #t "Test23:input: normalizing a bad polynomial: "
		    (make-polynomial 'y
				       (list (make-term 2 (make-polynomial
							   'x
							   (list (make-term 2 1) (make-term 0 1))))
					     (make-term 0 2))) "\n")
	      #;(show #t "Test23:result: normalizing a bad polynomial: "
		    (normalize-once (make-polynomial 'y
						     (list (make-term 2 (make-polynomial
									 'x
							   (list (make-term 2 1) (make-term 0 1))))
							   (make-term 0 2)))) "\n")
	      #;(show #t "Test24:input: normalizing a bad polynomial: "
		    (make-polynomial 'x
				       (list (make-term 2 (make-polynomial
							   'x
							   (list (make-term 2 1) (make-term 0 1))))
					     (make-term 0 2))) "\n")
	      #;(show #t "Test24:result: normalizing a bad polynomial: "
		    (normalize-once (make-polynomial 'x
						     (list (make-term 2 (make-polynomial
									 'x
							   (list (make-term 2 1) (make-term 0 1))))
							   (make-term 0 2)))) "\n")


	      #;(show #t "Test24:input: normalize-fully a bad polynomial: "
		    (make-polynomial 'y
				       (list (make-term 2 (make-polynomial
							   'x
							   (list (make-term 2 1) (make-term 0 1))))
					     (make-term 0 2))) "\n")
	      #;(show #t "Test24:result: normalize-fully a bad polynomial: "
		    (normalize-fully (make-polynomial 'y
						     (list (make-term 2 (make-polynomial
									 'x
							   (list (make-term 2 1) (make-term 0 1))))
							   (make-term 0 2)))) "\n")



	      'done)


	    (define (install-polynomial-sparse-package)
	      (define (coeff term) (cadr term))
	      (define (first-term-sparse term-list) (car term-list))
	      (define (adjoin-term-sparse term term-list)
		(if (zero? (coeff term))
		    term-list
		    (cons term term-list)))
	      (put 'adjoin-term 'sparse adjoin-term-sparse)
	      (put 'first-term 'sparse first-term-sparse)
	      'done)
	    (install-polynomial-sparse-package)

	    (define (install-polynomial-dense-package)
	      (define (make-term order coeff) (list order coeff))
	      (define (order term) (car term))
	      (define (coeff term) (cadr term))

	      (define (adjoin-term-dense term term-list)
		  (if (zero? (coeff term))
		      term-list
		      (if (> (order term) (length term-list))
			  (append (list (coeff term))
				  (make-list (- (order term) (length term-list)) 0)
				  term-list)
			  (error "adjoin-term:Appending a smaller order term. Recheck."))))
	      (define (first-term-dense term-list) 
		 #;(show #t "first-term-dense: " (displayed (make-term (car term-list) (length (cdr term-list)))) "\n")
		 (make-term (length (cdr term-list)) (car term-list) ))
	      (put 'adjoin-term 'dense adjoin-term-dense)
	      (put 'first-term 'dense first-term-dense)
	      'done)
	    #;(install-polynomial-dense-package)

	    (define (make-polynomial var terms)
	      ((get 'make 'polynomial) var terms))

	  (install-polynomial-package)


	    (show #t "Test 2: Making polynomials: " 
		  (make-polynomial 'x (list (list 5 1) (list 4 2))) "\n")
	    (show #t "Test 3: Zero?: " 
		  (zero? (make-polynomial 'x (list (list 5 1) (list 4 2)))) "\n")
	    (show #t "Test 4: Adding polynomials: "
		  (add (make-polynomial 'x '((5 1) (4 2) (0 1)))
		       (make-polynomial 'x '((5 1)))) "\n")
	    (show #t "Test 4: Zero?: " (zero? (make-polynomial 'x '((5 0) (3 1)))) "\n")

	    (show #t "Test 5: Subtracting polynomials: "
		  (sub (make-polynomial 'x '((5 1) (4 2) (0 1)))
		       (make-polynomial 'x '((0 1)))) "\n")

	    #;(show #t "Test 6: Making a dense polynomial: " (make-polynomial 'x '(1 2 3 4 5)) "\n")
	    #;(show #t "Test 7: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(0)))) "\n")
	    #;(show #t "Test 8: zero? dense polynomial: " (displayed (zero? (make-polynomial 'x '(1)))) "\n")
	    #;(show #t "Test 9: Adding dense polynomials: "
		  (add (make-polynomial 'x '(1 2 0 0 0 1))
		       (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
	    #;(show #t "Test10: Subtracting dense polynomials: "
		  (sub (make-polynomial 'x '(1 2 0 0 0 1))
		       (make-polynomial 'x '(1 0 0 0 0 0))) "\n")
	    #;(show #t "Test11: Subtracting dense and sparse polynomials: "
		  (sub (make-polynomial 'x '(1 2 0 0 0 1))
		       (make-polynomial 'x '((4 2)))) "\n")
	    (show #t "Test12: Dividing x^2 + 2x + 1 by x+1: "
		  (displayed
		   (div (make-polynomial 'x '((2 1) (1 2) (0 1)))
			(make-polynomial 'x '(      (1 1) (0 1)))) ) "\n")
	    (show #t "Test14: Adding polynomials of two variables: "
		  (displayed
		   (add (make-polynomial 'x '((1 1)))
			(make-polynomial 'y '((1 1))))))
	    (show #t "Test14: Adding polynomials of two variables, when one of them is nonexistant: "
		  (displayed
		   (add (make-polynomial 'x '((1 1)))
			(make-polynomial 'y '((0 1))))))
	    (show #t "Test25: multiplying different variables: "
		(displayed (mul (make-polynomial 'x '((1 1)))
				(make-polynomial 'y '((1 1))))) "\n")
	(begin
	(show #t "Test 26:start\n")
	(define p1 (make-polynomial 'x '((2 1) (0 1))))
	(define p2 (make-polynomial 'x '((3 1) (0 1))))
	(define rf (make-rational p2 p1))

	(show #t "Test 26: make-rational-polynomial: " rf "\n")
	(show #t "Test 27: add-rational\n")
	(show #t "Test 27: " (add rf rf) "\n")
	)

	(show #t "Test 28: polynomial-gcd: start\n")
	(define (greatest-common-divisor p1 p2) (apply-generic 'gcd p1 p2))
	(begin
	  (define p1 (make-polynomial
		       'x '((4 1) (3 -1) (2 -2) (1 2))))
	  (define p2 (make-polynomial 'x '((3 1) (1 -1))))

	  (show #t "Test 28: polynomial-gcd: " (greatest-common-divisor p1 p2) "\n"))

	(begin
	    (define p1 (make-polynomial
			 'x '((2 1) (1 -2) (0 1))))
	    (define p2 (make-polynomial 'x '((2 11) (0 7))))

	    (define p3 (make-polynomial 'x '((1 13) (0 5))))
	    (define q1 (mul p1 p2))
	    (define q2 (mul p1 p3))
	    (show #t "Test 29: gcd-integer-problem: start\n")
	    (show #t "Test 29: p1=" p1 "\n")
	    (show #t "Test 29: p2=" p2 "\n")
	    (show #t "Test 29: p3=" p3 "\n")
	    (show #t "Test 29: q1=" q1 "\n")
	    (show #t "Test 29: q2=" q2 "\n")
	    (show #t "Test 29: gcd : " (greatest-common-divisor q1 q2) "\n")      
	  )

  (begin 
                 (show #t "Test 30: start\n")
		 (define p1 (make-polynomial 'x '((1 1)(0 1))))
		 (define p2 (make-polynomial 'x '((3 1)(0 -1))))
		 (define p3 (make-polynomial 'x '((1 1))))
		 (define p4 (make-polynomial 'x '((2 1)(0 -1))))

		 (define rf1 (make-rational p1 p2))
		 (define rf2 (make-rational p3 p4))

		 (show #t "Test 33: " (add rf1 rf2) "\n"))


#+end_src

#+RESULTS:
#+begin_example
(tag 5)=5
Test 31: start
Test 31:#t
Test: Higher than 'integer: scheme-number
Test 30: start
Test 30:(add (make-scheme-number 1) (make-scheme-number 1))= 2
Test 32: startTest 32: Subtracting complex numbers: 1.1
TestY2: poly of poly: (x (3 (y (1 1) (0 1))) (1 2) (0 4))
zero-poly?: poly=(y (2 (polynomial x (2 1) (0 1))) (0 2))
zero-poly?: poly=(x (2 1) (0 1))
zero-poly?: poly=(y (0 2))
zero-poly?: poly=(y)
zero-poly?: poly=(x (2 1) (0 1))
zero-poly?: poly=(y (2 (polynomial x (2 1) (0 1))) (0 2))
zero-poly?: poly=(x (2 1) (0 1))
zero-poly?: poly=(x (2 1) (0 1))
zero-poly?: poly=(x (0 1))
zero-poly?: poly=(x)
zero-poly?: poly=(y (0 2))
zero-poly?: poly=(y)
zero-poly?: poly=(y (2 1))
zero-poly?: poly=(y (2 1))
zero-poly?: poly=(y (2 1) (0 2))
zero-poly?: poly=(y (2 1))
Test13: Expanding a polynomial as monomials: (polynomial x (2 (polynomial y (2 1))) (0 (polynomial y (2 1) (0 2))))

Test20: start monomial: (polynomial x (2 (polynomial y (2 1) (0 1))))
zero-poly?: poly=(x (1 1))
zero-poly?: poly=(x (1 1))
Test20: Flipping a monomial variable: (polynomial y (2 (polynomial x (1 1))) (0 (polynomial x (1 1))))

Test21: normal-polynomial?:start: (polynomial y (2 (polynomial x (2 1) (0 1))) (0 2))
Test 2: Making polynomials: (polynomial x (5 1) (4 2))
zero-poly?: poly=(x (5 1) (4 2))
Test 3: Zero?: #f
Test 4: Adding polynomials: (polynomial x (5 2) (4 2) (0 1))
zero-poly?: poly=(x (5 0) (3 1))
zero-poly?: poly=(x (3 1))
Test 4: Zero?: #f
Test 5: Subtracting polynomials: (polynomial x (5 1) (4 2))
div-poly: p1=(x (2 1) (1 2) (0 1)), p2=(x (1 1) (0 1))
div-terms: L1=((2 1) (1 2) (0 1)), L2=((1 1) (0 1))
div-terms: L1=((1 1) (0 1)), L2=((1 1) (0 1))
div-terms: L1=(), L2=((1 1) (0 1))
Test12: Dividing x^2 + 2x + 1 by x+1: ((x (1 1) (0 1)) (x))
Test14: Adding polynomials of two variables: (polynomial x (1 1) (0 (polynomial y (1 1))))Test14: Adding polynomials of two variables, when one of them is nonexistant: (polynomial x (1 1) (0 (polynomial y (0 1))))zero-poly?: poly=(y (1 1))
zero-poly?: poly=(y (1 1))
Test25: multiplying different variables: (polynomial x (1 (polynomial y (1 1))))
Test 26:start
make-rat: n=(polynomial x (3 1) (0 1)), d=(polynomial x (2 1) (0 1))
reduce-poly: p1=(x (3 1) (0 1)), p2=(x (2 1) (0 1))
reduce-terms: termlist-1=((3 1) (0 1)), termlist-2=((2 1) (0 1))
gcd-terms: a=((3 1) (0 1)), b=((2 1) (0 1))
pseudoremainder-terms: P=((3 1) (0 1))
pseudoremainder-terms: Q=((2 1) (0 1))
pseudoremainder-terms: O1=3
pseudoremainder-terms: O2=2
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((3 1) (0 1))
div-terms: L1=((3 1) (0 1)), L2=((2 1) (0 1))
div-terms: L1=((1 -1) (0 1)), L2=((2 1) (0 1))
gcd-terms: a=((2 1) (0 1)), b=((1 -1) (0 1))
pseudoremainder-terms: P=((2 1) (0 1))
pseudoremainder-terms: Q=((1 -1) (0 1))
pseudoremainder-terms: O1=2
pseudoremainder-terms: O2=1
pseudoremainder-terms: c=-1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((2 1) (0 1))
div-terms: L1=((2 1) (0 1)), L2=((1 -1) (0 1))
div-terms: L1=((1 1) (0 1)), L2=((1 -1) (0 1))
div-terms: L1=((0 2)), L2=((1 -1) (0 1))
gcd-terms: a=((1 -1) (0 1)), b=((0 2))
pseudoremainder-terms: P=((1 -1) (0 1))
pseudoremainder-terms: Q=((0 2))
pseudoremainder-terms: O1=1
pseudoremainder-terms: O2=0
pseudoremainder-terms: c=2
pseudoremainder-terms: the integerizing factor=(0 4)
pseudoremainder-terms: P after multiplication=((1 -4) (0 4))
div-terms: L1=((1 -4) (0 4)), L2=((0 2))
div-terms: L1=((0 4)), L2=((0 2))
div-terms: L1=(), L2=((0 2))
gcd-terms: a=((0 2)), b=()
div-terms: L1=((3 16) (0 16)), L2=((0 2))
div-terms: L1=((0 16)), L2=((0 2))
div-terms: L1=(), L2=((0 2))
div-terms: L1=((2 16) (0 16)), L2=((0 2))
div-terms: L1=((0 16)), L2=((0 2))
div-terms: L1=(), L2=((0 2))
maprest: operation=#<procedure first-term>term-list=((3 8) (0 8))
maprest: operation=#<procedure first-term>term-list=((0 8))
maprest: operation=#<procedure first-term>term-list=()
maprest: operation=#<procedure first-term>term-list=((2 8) (0 8))
maprest: operation=#<procedure first-term>term-list=((0 8))
maprest: operation=#<procedure first-term>term-list=()
full-list=(8 8 8 8)
Test 26: make-rational-polynomial: (rational (polynomial x (3 1) (0 1)) polynomial x (2 1) (0 1))
Test 27: add-rational
make-rat: n=(polynomial x (5 2) (3 2) (2 2) (0 2)), d=(polynomial x (4 1) (2 2) (0 1))
reduce-poly: p1=(x (5 2) (3 2) (2 2) (0 2)), p2=(x (4 1) (2 2) (0 1))
reduce-terms: termlist-1=((5 2) (3 2) (2 2) (0 2)), termlist-2=((4 1) (2 2) (0 1))
gcd-terms: a=((5 2) (3 2) (2 2) (0 2)), b=((4 1) (2 2) (0 1))
pseudoremainder-terms: P=((5 2) (3 2) (2 2) (0 2))
pseudoremainder-terms: Q=((4 1) (2 2) (0 1))
pseudoremainder-terms: O1=5
pseudoremainder-terms: O2=4
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((5 2) (3 2) (2 2) (0 2))
div-terms: L1=((5 2) (3 2) (2 2) (0 2)), L2=((4 1) (2 2) (0 1))
div-terms: L1=((3 -2) (2 2) (1 -2) (0 2)), L2=((4 1) (2 2) (0 1))
gcd-terms: a=((4 1) (2 2) (0 1)), b=((3 -2) (2 2) (1 -2) (0 2))
pseudoremainder-terms: P=((4 1) (2 2) (0 1))
pseudoremainder-terms: Q=((3 -2) (2 2) (1 -2) (0 2))
pseudoremainder-terms: O1=4
pseudoremainder-terms: O2=3
pseudoremainder-terms: c=-2
pseudoremainder-terms: the integerizing factor=(0 4)
pseudoremainder-terms: P after multiplication=((4 4) (2 8) (0 4))
div-terms: L1=((4 4) (2 8) (0 4)), L2=((3 -2) (2 2) (1 -2) (0 2))
div-terms: L1=((3 4) (2 4) (1 4) (0 4)), L2=((3 -2) (2 2) (1 -2) (0 2))
div-terms: L1=((2 8) (0 8)), L2=((3 -2) (2 2) (1 -2) (0 2))
gcd-terms: a=((3 -2) (2 2) (1 -2) (0 2)), b=((2 8) (0 8))
pseudoremainder-terms: P=((3 -2) (2 2) (1 -2) (0 2))
pseudoremainder-terms: Q=((2 8) (0 8))
pseudoremainder-terms: O1=3
pseudoremainder-terms: O2=2
pseudoremainder-terms: c=8
pseudoremainder-terms: the integerizing factor=(0 64)
pseudoremainder-terms: P after multiplication=((3 -128) (2 128) (1 -128) (0 128))
div-terms: L1=((3 -128) (2 128) (1 -128) (0 128)), L2=((2 8) (0 8))
div-terms: L1=((2 128) (0 128)), L2=((2 8) (0 8))
div-terms: L1=(), L2=((2 8) (0 8))
gcd-terms: a=((2 8) (0 8)), b=()
div-terms: L1=((5 8192) (3 8192) (2 8192) (0 8192)), L2=((2 8) (0 8))
div-terms: L1=((2 8192) (0 8192)), L2=((2 8) (0 8))
div-terms: L1=(), L2=((2 8) (0 8))
div-terms: L1=((4 4096) (2 8192) (0 4096)), L2=((2 8) (0 8))
div-terms: L1=((2 4096) (0 4096)), L2=((2 8) (0 8))
div-terms: L1=(), L2=((2 8) (0 8))
maprest: operation=#<procedure first-term>term-list=((3 1024) (0 1024))
maprest: operation=#<procedure first-term>term-list=((0 1024))
maprest: operation=#<procedure first-term>term-list=()
maprest: operation=#<procedure first-term>term-list=((2 512) (0 512))
maprest: operation=#<procedure first-term>term-list=((0 512))
maprest: operation=#<procedure first-term>term-list=()
full-list=(1024 1024 512 512)
rational not droppable: #f
Test 27: (rational (polynomial x (3 2) (0 2)) polynomial x (2 1) (0 1))
Test 28: polynomial-gcd: start
gcd-poly:p1=(x (4 1) (3 -1) (2 -2) (1 2)), p2=(x (3 1) (1 -1))
gcd-terms: a=((4 1) (3 -1) (2 -2) (1 2)), b=((3 1) (1 -1))
pseudoremainder-terms: P=((4 1) (3 -1) (2 -2) (1 2))
pseudoremainder-terms: Q=((3 1) (1 -1))
pseudoremainder-terms: O1=4
pseudoremainder-terms: O2=3
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((4 1) (3 -1) (2 -2) (1 2))
div-terms: L1=((4 1) (3 -1) (2 -2) (1 2)), L2=((3 1) (1 -1))
div-terms: L1=((3 -1) (2 -1) (1 2)), L2=((3 1) (1 -1))
div-terms: L1=((2 -1) (1 1)), L2=((3 1) (1 -1))
gcd-terms: a=((3 1) (1 -1)), b=((2 -1) (1 1))
pseudoremainder-terms: P=((3 1) (1 -1))
pseudoremainder-terms: Q=((2 -1) (1 1))
pseudoremainder-terms: O1=3
pseudoremainder-terms: O2=2
pseudoremainder-terms: c=-1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((3 1) (1 -1))
div-terms: L1=((3 1) (1 -1)), L2=((2 -1) (1 1))
div-terms: L1=((2 1) (1 -1)), L2=((2 -1) (1 1))
div-terms: L1=(), L2=((2 -1) (1 1))
gcd-terms: a=((2 -1) (1 1)), b=()
maprest: operation=#<procedure first-term>term-list=((2 -1) (1 1))
maprest: operation=#<procedure first-term>term-list=((1 1))
maprest: operation=#<procedure first-term>term-list=()
gcd-poly: unoptimized-termlist=((2 -1) (1 1))
gcd-poly: first-terms=((2 -1) (1 1))
gcd-poly: coefficients=(-1 1)
gcd-poly: coeff-gcd=1
Test 28: polynomial-gcd: (polynomial x (2 -1) (1 1))
Test 29: gcd-integer-problem: start
Test 29: p1=(polynomial x (2 1) (1 -2) (0 1))
Test 29: p2=(polynomial x (2 11) (0 7))
Test 29: p3=(polynomial x (1 13) (0 5))
Test 29: q1=(polynomial x (4 11) (3 -22) (2 18) (1 -14) (0 7))
Test 29: q2=(polynomial x (3 13) (2 -21) (1 3) (0 5))
gcd-poly:p1=(x (4 11) (3 -22) (2 18) (1 -14) (0 7)), p2=(x (3 13) (2 -21) (1 3) (0 5))
gcd-terms: a=((4 11) (3 -22) (2 18) (1 -14) (0 7)), b=((3 13) (2 -21) (1 3) (0 5))
pseudoremainder-terms: P=((4 11) (3 -22) (2 18) (1 -14) (0 7))
pseudoremainder-terms: Q=((3 13) (2 -21) (1 3) (0 5))
pseudoremainder-terms: O1=4
pseudoremainder-terms: O2=3
pseudoremainder-terms: c=13
pseudoremainder-terms: the integerizing factor=(0 169)
pseudoremainder-terms: P after multiplication=((4 1859) (3 -3718) (2 3042) (1 -2366) (0 1183))
div-terms: L1=((4 1859) (3 -3718) (2 3042) (1 -2366) (0 1183)), L2=((3 13) (2 -21) (1 3) (0 5))
div-terms: L1=((3 -715) (2 2613) (1 -3081) (0 1183)), L2=((3 13) (2 -21) (1 3) (0 5))
div-terms: L1=((2 1458) (1 -2916) (0 1458)), L2=((3 13) (2 -21) (1 3) (0 5))
gcd-terms: a=((3 13) (2 -21) (1 3) (0 5)), b=((2 1458) (1 -2916) (0 1458))
pseudoremainder-terms: P=((3 13) (2 -21) (1 3) (0 5))
pseudoremainder-terms: Q=((2 1458) (1 -2916) (0 1458))
pseudoremainder-terms: O1=3
pseudoremainder-terms: O2=2
pseudoremainder-terms: c=1458
pseudoremainder-terms: the integerizing factor=(0 2125764)
pseudoremainder-terms: P after multiplication=((3 27634932) (2 -44641044) (1 6377292) (0 10628820))
div-terms: L1=((3 27634932) (2 -44641044) (1 6377292) (0 10628820)), L2=((2 1458) (1 -2916) (0 1458))
div-terms: L1=((2 10628820) (1 -21257640) (0 10628820)), L2=((2 1458) (1 -2916) (0 1458))
div-terms: L1=(), L2=((2 1458) (1 -2916) (0 1458))
gcd-terms: a=((2 1458) (1 -2916) (0 1458)), b=()
maprest: operation=#<procedure first-term>term-list=((2 1458) (1 -2916) (0 1458))
maprest: operation=#<procedure first-term>term-list=((1 -2916) (0 1458))
maprest: operation=#<procedure first-term>term-list=((0 1458))
maprest: operation=#<procedure first-term>term-list=()
gcd-poly: unoptimized-termlist=((2 1458) (1 -2916) (0 1458))
gcd-poly: first-terms=((2 1458) (1 -2916) (0 1458))
gcd-poly: coefficients=(1458 -2916 1458)
gcd-poly: coeff-gcd=1458
Test 29: gcd : (polynomial x (2 0.9999999999999999) (1 -1.9999999999999998) (0 0.9999999999999999))
Test 30: start
make-rat: n=(polynomial x (1 1) (0 1)), d=(polynomial x (3 1) (0 -1))
reduce-poly: p1=(x (1 1) (0 1)), p2=(x (3 1) (0 -1))
reduce-terms: termlist-1=((1 1) (0 1)), termlist-2=((3 1) (0 -1))
gcd-terms: a=((1 1) (0 1)), b=((3 1) (0 -1))
pseudoremainder-terms: P=((1 1) (0 1))
pseudoremainder-terms: Q=((3 1) (0 -1))
pseudoremainder-terms: O1=1
pseudoremainder-terms: O2=3
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((1 1) (0 1))
div-terms: L1=((1 1) (0 1)), L2=((3 1) (0 -1))
gcd-terms: a=((3 1) (0 -1)), b=((1 1) (0 1))
pseudoremainder-terms: P=((3 1) (0 -1))
pseudoremainder-terms: Q=((1 1) (0 1))
pseudoremainder-terms: O1=3
pseudoremainder-terms: O2=1
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((3 1) (0 -1))
div-terms: L1=((3 1) (0 -1)), L2=((1 1) (0 1))
div-terms: L1=((2 -1) (0 -1)), L2=((1 1) (0 1))
div-terms: L1=((1 1) (0 -1)), L2=((1 1) (0 1))
div-terms: L1=((0 -2)), L2=((1 1) (0 1))
gcd-terms: a=((1 1) (0 1)), b=((0 -2))
pseudoremainder-terms: P=((1 1) (0 1))
pseudoremainder-terms: Q=((0 -2))
pseudoremainder-terms: O1=1
pseudoremainder-terms: O2=0
pseudoremainder-terms: c=-2
pseudoremainder-terms: the integerizing factor=(0 4)
pseudoremainder-terms: P after multiplication=((1 4) (0 4))
div-terms: L1=((1 4) (0 4)), L2=((0 -2))
div-terms: L1=((0 4)), L2=((0 -2))
div-terms: L1=(), L2=((0 -2))
gcd-terms: a=((0 -2)), b=()
div-terms: L1=((1 16) (0 16)), L2=((0 -2))
div-terms: L1=((0 16)), L2=((0 -2))
div-terms: L1=(), L2=((0 -2))
div-terms: L1=((3 16) (0 -16)), L2=((0 -2))
div-terms: L1=((0 -16)), L2=((0 -2))
div-terms: L1=(), L2=((0 -2))
maprest: operation=#<procedure first-term>term-list=((1 -8) (0 -8))
maprest: operation=#<procedure first-term>term-list=((0 -8))
maprest: operation=#<procedure first-term>term-list=()
maprest: operation=#<procedure first-term>term-list=((3 -8) (0 8))
maprest: operation=#<procedure first-term>term-list=((0 8))
maprest: operation=#<procedure first-term>term-list=()
full-list=(-8 -8 -8 8)
make-rat: n=(polynomial x (1 1)), d=(polynomial x (2 1) (0 -1))
reduce-poly: p1=(x (1 1)), p2=(x (2 1) (0 -1))
reduce-terms: termlist-1=((1 1)), termlist-2=((2 1) (0 -1))
gcd-terms: a=((1 1)), b=((2 1) (0 -1))
pseudoremainder-terms: P=((1 1))
pseudoremainder-terms: Q=((2 1) (0 -1))
pseudoremainder-terms: O1=1
pseudoremainder-terms: O2=2
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((1 1))
div-terms: L1=((1 1)), L2=((2 1) (0 -1))
gcd-terms: a=((2 1) (0 -1)), b=((1 1))
pseudoremainder-terms: P=((2 1) (0 -1))
pseudoremainder-terms: Q=((1 1))
pseudoremainder-terms: O1=2
pseudoremainder-terms: O2=1
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((2 1) (0 -1))
div-terms: L1=((2 1) (0 -1)), L2=((1 1))
div-terms: L1=((0 -1)), L2=((1 1))
gcd-terms: a=((1 1)), b=((0 -1))
pseudoremainder-terms: P=((1 1))
pseudoremainder-terms: Q=((0 -1))
pseudoremainder-terms: O1=1
pseudoremainder-terms: O2=0
pseudoremainder-terms: c=-1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((1 1))
div-terms: L1=((1 1)), L2=((0 -1))
div-terms: L1=(), L2=((0 -1))
gcd-terms: a=((0 -1)), b=()
div-terms: L1=((1 -1)), L2=((0 -1))
div-terms: L1=(), L2=((0 -1))
div-terms: L1=((2 -1) (0 1)), L2=((0 -1))
div-terms: L1=((0 1)), L2=((0 -1))
div-terms: L1=(), L2=((0 -1))
maprest: operation=#<procedure first-term>term-list=((1 1))
maprest: operation=#<procedure first-term>term-list=()
maprest: operation=#<procedure first-term>term-list=((2 1) (0 -1))
maprest: operation=#<procedure first-term>term-list=((0 -1))
maprest: operation=#<procedure first-term>term-list=()
full-list=(1 1 -1)
make-rat: n=(polynomial x (4 -1) (3 -1) (2 -1) (1 2) (0 1)), d=(polynomial x (5 -1) (3 1) (2 1) (0 -1))
reduce-poly: p1=(x (4 -1) (3 -1) (2 -1) (1 2) (0 1)), p2=(x (5 -1) (3 1) (2 1) (0 -1))
reduce-terms: termlist-1=((4 -1) (3 -1) (2 -1) (1 2) (0 1)), termlist-2=((5 -1) (3 1) (2 1) (0 -1))
gcd-terms: a=((4 -1) (3 -1) (2 -1) (1 2) (0 1)), b=((5 -1) (3 1) (2 1) (0 -1))
pseudoremainder-terms: P=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
pseudoremainder-terms: Q=((5 -1) (3 1) (2 1) (0 -1))
pseudoremainder-terms: O1=4
pseudoremainder-terms: O2=5
pseudoremainder-terms: c=-1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
div-terms: L1=((4 -1) (3 -1) (2 -1) (1 2) (0 1)), L2=((5 -1) (3 1) (2 1) (0 -1))
gcd-terms: a=((5 -1) (3 1) (2 1) (0 -1)), b=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
pseudoremainder-terms: P=((5 -1) (3 1) (2 1) (0 -1))
pseudoremainder-terms: Q=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
pseudoremainder-terms: O1=5
pseudoremainder-terms: O2=4
pseudoremainder-terms: c=-1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((5 -1) (3 1) (2 1) (0 -1))
div-terms: L1=((5 -1) (3 1) (2 1) (0 -1)), L2=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
div-terms: L1=((4 1) (3 2) (2 -1) (1 -1) (0 -1)), L2=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
div-terms: L1=((3 1) (2 -2) (1 1)), L2=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
gcd-terms: a=((4 -1) (3 -1) (2 -1) (1 2) (0 1)), b=((3 1) (2 -2) (1 1))
pseudoremainder-terms: P=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
pseudoremainder-terms: Q=((3 1) (2 -2) (1 1))
pseudoremainder-terms: O1=4
pseudoremainder-terms: O2=3
pseudoremainder-terms: c=1
pseudoremainder-terms: the integerizing factor=(0 1)
pseudoremainder-terms: P after multiplication=((4 -1) (3 -1) (2 -1) (1 2) (0 1))
div-terms: L1=((4 -1) (3 -1) (2 -1) (1 2) (0 1)), L2=((3 1) (2 -2) (1 1))
div-terms: L1=((3 -3) (1 2) (0 1)), L2=((3 1) (2 -2) (1 1))
div-terms: L1=((2 -6) (1 5) (0 1)), L2=((3 1) (2 -2) (1 1))
gcd-terms: a=((3 1) (2 -2) (1 1)), b=((2 -6) (1 5) (0 1))
pseudoremainder-terms: P=((3 1) (2 -2) (1 1))
pseudoremainder-terms: Q=((2 -6) (1 5) (0 1))
pseudoremainder-terms: O1=3
pseudoremainder-terms: O2=2
pseudoremainder-terms: c=-6
pseudoremainder-terms: the integerizing factor=(0 36)
pseudoremainder-terms: P after multiplication=((3 36) (2 -72) (1 36))
div-terms: L1=((3 36) (2 -72) (1 36)), L2=((2 -6) (1 5) (0 1))
div-terms: L1=((2 -42) (1 42)), L2=((2 -6) (1 5) (0 1))
div-terms: L1=((1 7) (0 -7)), L2=((2 -6) (1 5) (0 1))
gcd-terms: a=((2 -6) (1 5) (0 1)), b=((1 7) (0 -7))
pseudoremainder-terms: P=((2 -6) (1 5) (0 1))
pseudoremainder-terms: Q=((1 7) (0 -7))
pseudoremainder-terms: O1=2
pseudoremainder-terms: O2=1
pseudoremainder-terms: c=7
pseudoremainder-terms: the integerizing factor=(0 49)
pseudoremainder-terms: P after multiplication=((2 -294) (1 245) (0 49))
div-terms: L1=((2 -294) (1 245) (0 49)), L2=((1 7) (0 -7))
div-terms: L1=((1 -49) (0 49)), L2=((1 7) (0 -7))
div-terms: L1=(), L2=((1 7) (0 -7))
gcd-terms: a=((1 7) (0 -7)), b=()
div-terms: L1=((4 -16807) (3 -16807) (2 -16807) (1 33614) (0 16807)), L2=((1 7) (0 -7))
div-terms: L1=((3 -33614) (2 -16807) (1 33614) (0 16807)), L2=((1 7) (0 -7))
div-terms: L1=((2 -50421) (1 33614) (0 16807)), L2=((1 7) (0 -7))
div-terms: L1=((1 -16807) (0 16807)), L2=((1 7) (0 -7))
div-terms: L1=(), L2=((1 7) (0 -7))
div-terms: L1=((5 -16807) (3 16807) (2 16807) (0 -16807)), L2=((1 7) (0 -7))
div-terms: L1=((4 -16807) (3 16807) (2 16807) (0 -16807)), L2=((1 7) (0 -7))
div-terms: L1=((2 16807) (0 -16807)), L2=((1 7) (0 -7))
div-terms: L1=((1 16807) (0 -16807)), L2=((1 7) (0 -7))
div-terms: L1=(), L2=((1 7) (0 -7))
maprest: operation=#<procedure first-term>term-list=((3 -2401) (2 -4802) (1 -7203) (0 -2401))
maprest: operation=#<procedure first-term>term-list=((2 -4802) (1 -7203) (0 -2401))
maprest: operation=#<procedure first-term>term-list=((1 -7203) (0 -2401))
maprest: operation=#<procedure first-term>term-list=((0 -2401))
maprest: operation=#<procedure first-term>term-list=()
maprest: operation=#<procedure first-term>term-list=((4 -2401) (3 -2401) (1 2401) (0 2401))
maprest: operation=#<procedure first-term>term-list=((3 -2401) (1 2401) (0 2401))
maprest: operation=#<procedure first-term>term-list=((1 2401) (0 2401))
maprest: operation=#<procedure first-term>term-list=((0 2401))
maprest: operation=#<procedure first-term>term-list=()
full-list=(-2401 -4802 -7203 -2401 -2401 -2401 2401 2401)
rational not droppable: #f
Test 33: (rational (polynomial x (3 -1) (2 -2) (1 -3) (0 -1)) polynomial x (4 -1) (3 -1) (1 1) (0 1))
#+end_example

This exercise ends the Chapter 2 of the Structure and Interpretation of
Computer programs.

The main pedagogical conclusion one may infer from this exercise is that it
is a good idea to read a book on algebra and integer algorithms.
** TODO Chapter 3: Modularity, Objects and State [75/91]
*** DONE Exercise 3.1 accumulators
    CLOSED: [2019-10-29 Tue 10:24]

#+begin_src scheme :exports both :results output
(define (make-accumulator initial-amount)
   (lambda (increment) (set! initial-amount (+ initial-amount increment)) initial-amount))
(define A (make-accumulator 5))
(check (A 10) => 15)
(check (A 20) => 35)
(define B (make-accumulator 100))
(check (B 200) => 300)
(check (B   1) => 301)
#+end_src

#+RESULTS:
: 
: (A 10) => 15 ; correct
: 
: (A 20) => 35 ; correct
: 
: (B 200) => 300 ; correct
: 
: (B 1) => 301 ; correct

*** DONE Exercise 3.2 make-monitored
    CLOSED: [2019-10-29 Tue 11:03]

This problem is ill-defined. In particular, it doesn't specify whether we
should be counting calls to ~f~ only, or to ~mf~ in total, including the
calls to ~'how-many-calls?~. 

#+begin_src scheme :exports both :results output
  (define (make-monitored f)
    (let ((call-counter 0))
      (lambda (arg)
	(cond ((eq? arg 'reset-count) (set! call-counter 0))
	      ((eq? arg 'how-many-calls?) call-counter)
	      (else (begin (set! call-counter (+ 1 call-counter)) (f arg)))))))
  (define s (make-monitored sqrt))

  (check (s 100) => 10)
  (check (s 'how-many-calls?) => 1)
#+end_src

#+RESULTS:
: 
: (s 100) => 10 ; correct
: 
: (s (quote how-many-calls?)) => 1 ; correct

*** DONE Exercise 3.3 password protection
    CLOSED: [2019-10-29 Tue 11:17]

This exercise is slightly tricky in that it uses the less commonly used form
of ~lambda~, which can take any number of arguments.

#+begin_src scheme :exports both :results output
(define (make-account balance password)
       (define (withdraw amount)
         (if (>= balance amount)
             (begin (set! balance (- balance amount))
                    balance)
             "Insufficient funds"))
       (define (deposit amount)
         (set! balance (+ balance amount))
         balance)
       (define (dispatch pass m)
        (if (eq? pass password)
         (cond ((eq? m 'withdraw) withdraw)
               ((eq? m 'deposit) deposit)
               (else (error "Unknown request -- MAKE-ACCOUNT"
                            m)))
         (lambda rest "Incorrect password")))
       dispatch)

(define acc (make-account 100 'secret-password))

(check ((acc 'secret-password 'withdraw) 40) => 60)

(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")

#+end_src

#+RESULTS:
: 
: ((acc (quote secret-password) (quote withdraw)) 40) => 60 ; correct
: 
: ((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct

*** DONE Exercise 3.4 call-the-cops
    CLOSED: [2019-10-29 Tue 11:32]

#+begin_src scheme :exports both :results output
(define (make-account balance password)
       (define (withdraw amount)
         (if (>= balance amount)
             (begin (set! balance (- balance amount))
                    balance)
             "Insufficient funds"))
       (define (deposit amount)
         (set! balance (+ balance amount))
         balance)
       (let ((cops-counter 7))
        (define (call-the-cops) "Call the cops")
        (define (dispatch pass m)
        (if (eq? pass password)
         (cond ((eq? m 'withdraw) withdraw)
               ((eq? m 'deposit) deposit)
               (else (error "Unknown request -- MAKE-ACCOUNT"
                            m)))
         (lambda rest 
           (if (< 0 cops-counter)
             (begin (set! cops-counter (- cops-counter 1)) "Incorrect password")
             (call-the-cops)))))
       dispatch))

(define acc (make-account 100 'secret-password))

(check ((acc 'secret-password 'withdraw) 40) => 60)

(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")
(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")
(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")
(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")
(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")
(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")
(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")
(check ((acc 'some-other-password 'deposit) 50) => "Call the cops")

#+end_src

#+RESULTS:
#+begin_example

((acc (quote secret-password) (quote withdraw)) 40) => 60 ; correct

((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct

((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct

((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct

((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct

((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct

((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct

((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct

((acc (quote some-other-password) (quote deposit)) 50) => "Call the cops" ; correct
#+end_example

*** DONE Exercise 3.5 Monte-Carlo
    CLOSED: [2019-10-30 Wed 00:12]

I am using the random function first defined in Exercise 1.24, not the
rand-update, because I am not very sure in my prng development skills.

#+begin_src scheme :exports both :results output
  <<random>>
  (define (random-in-range low high)
      (let ((range (- high low)))
      (+ low (random range))))
  (show #t "Test 01: " (random-in-range 1 2000) "\n")

  (define (monte-carlo trials experiment)
    (define (iter trials-remaining trials-passed)
      (cond ((= trials-remaining 0)
	     (/ trials-passed trials))
	    ((experiment)
	     (iter (- trials-remaining 1) (+ trials-passed 1)))
	    (else
	     (iter (- trials-remaining 1) trials-passed))))
    (iter trials 0))

  (define (is-inside-circle? x y radius)
    #;(show #t "x=" x ", y=" y "\n")
    (if (< (+ (expt (- x 1000) 2) (expt (- y 1000) 2)) (expt radius 2))
	#t
	#f))

  (define (estimate-integral P x1 x2 y1 y2 trials)
    #;(show #t "estimate-integral: x1=" x1 ", x2=" x2 ", y1=" y1 ", y2=" y2 ", trials=" trials "\n")
    (monte-carlo trials
		 (lambda ()
		   (P (random-in-range x1 x2) (random-in-range y1 y2)))))

  (define (estimate-pi trials)
    (inexact (* 4 (estimate-integral
	  (lambda (x y) (is-inside-circle? x y 1000)) 1 2000 1 2000 trials))))
(show #t "Test 02:" (estimate-pi 100100) "\n")
#+end_src

#+RESULTS:
: Test 01: 907
: Test 02:3.148211788211788

It took me more time to understand what exactly is wanted than to write the
actual code.

*** DONE Exercise 3.6 reset a prng
    CLOSED: [2019-10-30 Wed 11:42]

All three components in the random formula are primes. Is this good?

#+begin_src scheme :exports both :results output


  (define rand

    (let ((seed 1))
      (define (rand-update x)
	(remainder (+ (* x 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111389)
		      211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111801)
		   2111111111111111111111111111111111111111227))
      (lambda (operation)
	(case operation
	  ('generate (begin (show #t "Seed=" seed "\n") (set! seed (rand-update seed)) seed))
	  ('reset (lambda (number)
		    (set! seed number)))
	  (else (error "rand: wrong operation" operation))))))
  (show #t "Test 01: First random call: " (rand 'generate) "\n")

  ((rand 'reset) 100)

  (show #t "Test 02: Second random call: " (rand 'generate) "\n")
#+end_src

#+RESULTS:
: Seed=1
: Test 01: First random call: 473684210526315790444679008925823330256457
: Seed=100
: Test 02: Second random call: 701754385964912314820502646968297937855541

*** DONE Exercise 3.7 Joint accounts
    CLOSED: [2019-10-30 Wed 13:07]

This exercise illustrates a fairly common thing in programming called
"wrapping" or "interfacing". 

#+begin_src scheme :exports both :results output
(define (make-account balance password)
       (define (withdraw amount)
         (if (>= balance amount)
             (begin (set! balance (- balance amount))
                    balance)
             "Insufficient funds"))
       (define (deposit amount)
         (set! balance (+ balance amount))
         balance)
       (define (dispatch pass m)
        (if (eq? pass password)
         (cond ((eq? m 'withdraw) withdraw)
               ((eq? m 'deposit) deposit)
               (else (error "Unknown request -- MAKE-ACCOUNT"
                            m)))
         (lambda rest "Incorrect password")))
       dispatch)

(define acc (make-account 100 'secret-password))

(check ((acc 'secret-password 'withdraw) 40) => 60)

(check ((acc 'some-other-password 'deposit) 50) => "Incorrect password")

(define (make-joint account main-password sub-password)
 (define (dispatch pass m)
        (if (eq? pass sub-password)
         (account main-password m)
         (lambda rest "Incorrect password")))
 dispatch)

(define peter-acc (make-account 100 'open-sesame))

(define paul-acc
 (make-joint peter-acc 'open-sesame 'rosebud))

(check ((peter-acc 'open-sesame 'withdraw) 40) => 60)
(check ((paul-acc  'rosebud     'deposit)  50) => 110)


#+end_src

#+RESULTS:
: 
: ((acc (quote secret-password) (quote withdraw)) 40) => 60 ; correct
: 
: ((acc (quote some-other-password) (quote deposit)) 50) => "Incorrect password" ; correct
: 
: ((peter-acc (quote open-sesame) (quote withdraw)) 40) => 60 ; correct
: 
: ((paul-acc (quote rosebud) (quote deposit)) 50) => 110 ; correct

*** DONE Exercise 3.8 Right-to-left vs Left-to-right
    CLOSED: [2019-10-30 Wed 13:45]

#+begin_src scheme :exports both :results output

(define (make-lock a)
  (lambda (arg)
    (if (= arg 0)
       (set! a 0))
    a))
(define f (make-lock 100))

(show #t "Test 01:" (+ (f 0) (f 1)) "\n")

(define-syntax plus-oneway
  (syntax-rules ()
    ((plus-oneway a b) (let* ((first a)
                              (second b))
                           (+ first second)))))
(define-syntax plus-otherway
  (syntax-rules ()
    ((plus-otherway a b) (let* ((first b)
                                (second a))
                           (+ first second)))))
(define g (make-lock 101))
(define h (make-lock 201))
(show #t "Test 02:" (plus-oneway   (g 0) (g 1)) "\n")
(show #t "Test 03:" (plus-otherway (h 0) (h 1)) "\n")

#+end_src

#+RESULTS:
: Test 01:100
: Test 02:0
: Test 03:201

This is a fun exercise, which is nicely illustrated using
macros. Unlike ~+~, ~let*~ is guaranteed to evaluate its parameters
top to bottom, so we can specify the order of evaluation. The order of
evaluation in the next ~+~ does not matter, because its arguments are
already values and so evaluate to themselves.

*** TODO COMMENT Figure 3.5                                                    :tikz:
#+name: remark-environments-tikz
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 800
#+header: :fit yes :headers '("\\usepackage{tikz}")
#+header: :buffer on
#+begin_src latex :results raw file :exports code :file figure-3-5.png
  
  \begin{tikzpicture}
  [color=white,
   scheme/.style={filldraw,
                  rectangle,
                  draw=white,
                  fill=black!50,
                  rounded corners,
                  minimum size=2cm,
                  align=left}
  ]

  \node (0,0) {};
  \node (0,6.5) {};  
  \node (13.0,0) {};
  \node (13.0,6.5) {};
    
  %\filldraw[scheme,label=center:{x:2}] (2.0,  4.5) rectangle (13.0,6.5) ;
  \path (7.5,5.5) node[scheme,minimum width=11.5cm,minimum height=2cm] { test }
  %\filldraw[scheme] (2.0,  2.0) rectangle (4.0 ,4.0) ;
  \path  (3.0,3.0) node[scheme] {E2};
  \filldraw[scheme] (5.0,  2.0) rectangle (7.0 ,4.0) ;
  \filldraw[scheme] (8.0,  2.0) rectangle (10.0,4.0) ;
  \filldraw[scheme] (11.0, 2.0) rectangle (13.0,4.0) ;

  \draw[fill=yellow,font=\verylarge,align=left] (1.0,5.5) node {global\\ env};

  \end{tikzpicture}
#+end_src

#+RESULTS: remark-environments-tikz
[[file:figure-3-9.png]]

*** DONE Exercise 3.9 Environment structures
    CLOSED: [2019-11-20 Wed 14:28]

Okay, this is not a very good solution. I only display the
environments, and the code is only displayed to clarify the
environments. The ~if~ special forms are expanded.

Let us draw the environment number 1.

#+name: exercise-3-9-part-1
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-9-part-1.png
\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
     font=\sffamily,pics/two dots/.style={code={
     \node [draw,minimum size=5mm,circle,colored tokens={black!50}] 
     (#1-left) {};
    \node [draw,minimum size=5mm,circle,colored tokens={black!50},
    right=0pt of #1-left]
        (#1-right) {};
    \node [rectangle, fit=(#1-left) (#1-right)] (#1){};
    }},
    every pin edge/.style={<-,very thick},
    box/.style={draw,rectangle,inner sep=#1},box/.default=2mm]
  % 
  \node (W1)  {factorial:};
  \node (fake1) [right=190mm of W1] {};  
  %
  \node (g env) [box, fit=(W1) (fake1),
  pin={[text width=1cm,pin distance=10mm]left:global env}]
  { };
  %
  \path ([yshift=-20mm]W1.east)pic{two dots=w1fun}
    (w1fun) edge [<-, to path={|- (\tikztotarget)}] (W1.east);
  %
  \node [below=of w1fun-left, align=left] {parameters: n \\ body: \dots}
    edge [<-] (w1fun-left.center); 
  
  \path (w1fun-right.center) edge[->,to path={-| (\tikztotarget)}] 
    (node cs:name=g env,angle=183);
\path (g env.south west) -- (g env.south east)
\foreach \idx in {1,...,5}  
{  
  node [pos=1/7.5+\idx/7.5] (fake2-\idx)  {}
  node (E\idx-env) [below=5mm of fake2-\idx,box,
    pin={[pin distance=5mm]left:E\idx}] {n:\idx}
    edge [->] (fake2-\idx)
  
  node (E\idx-code) [below=5mm of E\idx-env, align=center]{
       (* \the\numexpr7-\idx \hskip5pt (factorial \the\numexpr6-\idx))
    }
} 
node [pos=1/7.5+6/7.5] (fake2-6) {}
node (E6-env) [below=5mm of fake2-6,box,
    pin={[pin distance=5mm]left:E6}] {n:1}
    edge [->] (fake2-6)
node (E6-code) [below=5mm of E6-env, align=center]{
       1
    };
%\draw (g env.south east) node [draw=red,rectangle]  {debug};
\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-9-part-1
[[file:exercise-3-9-part-1.png]]


Let us draw the environment number 2.


#+name: exercise-3-9-part-2
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-9-part-2.png
\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
     font=\sffamily,pics/two dots/.style={code={
     \node [draw,minimum size=5mm,circle,colored tokens={black!50}] 
     (#1-left) {};
    \node [draw,minimum size=5mm,circle,colored tokens={black!50},
    right=0pt of #1-left]
        (#1-right) {};
    \node [rectangle, fit=(#1-left) (#1-right)] (#1){};
    }},
    every pin edge/.style={<-,very thick},
    box/.style={draw,rectangle,inner sep=#1},box/.default=2mm]

  \node (W1)   {factorial:};
  \node (fake1) [right=340mm of W1] {};  
  \node (fact-iter) [above=1mm of W1] {fact-iter:};
%
  \node (g env) [box, fit=(W1) (fake1) (fact-iter),
  pin={[text width=1cm,pin distance=10mm]left:global env}]
  { };
  % factorial
  \path ([yshift=-20mm]W1.east)pic{two dots=w1fun}
    (w1fun) edge [<-, to path={|- (\tikztotarget)}] (W1.east);
  \node [below=of w1fun-left, align=left] {\ttfamily \noindent parameters:\vphantom{d}n \\ body: \dots}
    edge [<-] (w1fun-left.center); 
  \draw[->] (w1fun-right.center) -| ([xshift=3mm] w1fun-right.east |- g env.south);

  % fact-iter
\path coordinate[base right=22mm of w1fun.east] (aux)
    (aux) pic{two dots=fact-iter-fun}
    (fact-iter-fun) edge [<-, to path={|- (\tikztotarget)}] (fact-iter.east);
  \node [below=of fact-iter-fun-left, align=left,node font=\ttfamily] {
     parameters:product,\\
     \phantom{parameters:}counter,\\
     \phantom{parameters:}max-count \\ body: \dots}
    edge [<-] (fact-iter-fun-left.center); 
  \draw[->] (fact-iter-fun-right.center) -| ([xshift=3mm] fact-iter-fun-right.east |- g env.south);

\path (g env.south west) -- (g env.south east)
\foreach \idx in {1,...,6}  
{  
  
  node [pos=2.6/7.5+\idx/11] (fake2-\idx)  {}
  node (E\idx-env) [below=5mm of fake2-\idx,box,
    pin={[pin distance=5mm]left:E\idx}, align=left] {
        counter:\idx\\
        product:\pgfmathparse{int(factorial(\idx-1))}\pgfmathresult \\
        max-count:6}
    edge [->] (fake2-\idx)

  node (E\idx-code) [below=5mm of E\idx-env, align=left]{
       (fact-iter\\
        (* counter product) \\
       (+ counter 1)  \\
       max-count)
    }
}
node [pos=2.6/7.5+7/11] (fake2-7) {}
node (E7-env) [below=5mm of fake2-7,box,
    pin={[pin distance=5mm]left:E7},align=left] 
    {counter:7\\
     product:\pgfmathparse{int(factorial(7-1))}\pgfmathresult \\
     max-count:6
    }
    edge [->] (fake2-7)
node (E7-code) [below=5mm of E7-env, align=center]{
       720
    }
node [pos=2.0/7.5] (fake2-0) {}
node (E0-env) [below=5mm of fake2-0, box,
    pin={[pin distance=5mm]left:E0},align=left]
    {n:6}
    edge [->] (fake2-0)
node (E0-code) [below=5mm of E0-env, align=left]{
  (fact-iter 1 1 n)}
;

\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-9-part-2
[[file:exercise-3-9-part-2.png]]

These pictures would have never happened unless generous people from
TeX StackExchange had helped.

 - https://tex.stackexchange.com/questions/515909/how-to-make-this-tikz-picture-more-idiomatic-environment-diagram/515913
 - https://tex.stackexchange.com/questions/516560/how-to-place-evenly-spaced-nodes-in-tikz-from-node1-to-node2
 - https://tex.stackexchange.com/questions/517061/how-to-debug-token-positions-in-petri-nets-in-tikz
 - https://tex.stackexchange.com/questions/517217/how-is-text-indented-and-glued-within-tikz-node-contents

I feel that these diagrams are already quite cluttered, so I am
implicitly expanding ~if~ forms in the "code" blocks. I am also
ignoring top level commands and I am not drawing arrows when function
calls occur.[fn:2]

*** TODO Figure 3.9 Environments after the call to W1

#+name: remark-environments-3-9
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 800
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file figure-3-9.png
\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50]
\begin{scope} [node distance=4mm]
\node (make withdraw) {make-withdraw: ...};
\node (fake1) [right=of make withdraw,xshift=40mm] {};
\node (W1) [below=of make withdraw.west,anchor=west] {W1:};
\end{scope}

\node (g env) [draw,rectangle,inner sep=2mm, fit=(make withdraw) (W1) (fake1)]
{ };

\node (g env name) [left={of g env},text width=1cm]
{global env} edge[->,very thick] (g env);

\begin{scope}[node distance=0mm]
\node [draw,minimum size=5mm,circle,tokens=1,below=of W1.east, yshift=-20mm] (w1fun-left) {};
\node [draw,minimum size=5mm,circle,tokens=1,right=of w1fun-left, xshift=0mm]
(w1fun-right) {};

\node [rectangle, fit=(w1fun-left) (w1fun-right)] (w1fun)
{} edge [<-, to path={|- (\tikztotarget)}] (W1.east);
\end{scope}

\node [below=of w1fun-left, align=left] {parameters: amount \\ body:...}
edge [<-] (w1fun-left.center); 


\node (E1-env) [below=of g env,yshift=5mm,draw,inner sep=2mm] {balance: amount}
edge [->] (g env);
\node [left=of E1-env,xshift=5mm] {E1} edge [->] (E1-env);

\path (w1fun-right.center) edge[->,to path={-| (\tikztotarget)}] (E1-env.south);

\end{tikzpicture}


#+end_src

#+RESULTS: remark-environments-3-9
[[file:figure-3-9.png]]

*** DONE Exercise 3.10 Using ~let~ to create state variables
    CLOSED: [2019-11-25 Mon 12:52]

We need to compare two versions of ~make-withdraw~, the one using a
parameter variable as a state variable, the one created automatically,
and the one which creates a state variable explicitly using ~let~.

The first one:
#+begin_src scheme :exports both :results output
(define (make-withdraw balance)
  (lambda (amount)
    (if (>= balance amount)
      (begin (set! balance (- balance amount))
             balance)
"Insufficient funds")))
#+end_src

#+name: exercise-3-10-part-1
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-10-part-1.png
\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
     font=\sffamily,pics/two dots/.style={code={
     \node [draw,minimum size=5mm,circle,colored tokens={black!50}] 
     (#1-left) {};
    \node [draw,minimum size=5mm,circle,colored tokens={black!50},
    right=0pt of #1-left]
        (#1-right) {};
    \node [rectangle, fit=(#1-left) (#1-right)] (#1){};
    }},
    every pin edge/.style={<-,very thick},
    box/.style={draw,rectangle,inner sep=#1},box/.default=2mm]

  \node (W1)   {make-withdraw:};
  \node (fake1) [right=100mm of W1] {};  
  \node (fact-iter) [above=3mm of W1.west,anchor=west] {W1:};
%
  \node (g env) [box, fit=(W1) (fake1) (fact-iter),
  pin={[text width=1cm,pin distance=10mm]left:global env}]
  { };

  \path ([yshift=-20mm]W1.east)pic{two dots=w1fun}
    (w1fun) edge [<-, to path={|- (\tikztotarget)}] (W1.east);
  \node [below=of w1fun-left, align=left,font=\ttfamily] 
{\noindent parameters:\vphantom{d}balance \\ 
body:\\ 
  (lambda (amount)\\
    (if (>= balance amount)\\
      (begin (set! balance\\ (- balance amount))\\
             balance)\\
"Insufficient funds"))
}
    edge [<-] (w1fun-left.center); 
  \draw[->] (w1fun-right.center) -| ([xshift=3mm] w1fun-right.east |- g env.south);

\path (g env.south west) -- (g env.south east)
node [pos=7/8] (fake2-7) {}
node (E7-env) [below=5mm of fake2-7,box,
    pin={[pin distance=5mm]left:E1},align=left] 
    {balance:100}
    edge [->] (fake2-7) ;

\path coordinate[below right=5mm and 40mm of w1fun] (aux)
    (aux) pic{two dots=fact-iter-fun}
    (fact-iter-fun) edge [<-, to path={|- (\tikztotarget)}] (fact-iter.east);
  \node [below=of fact-iter-fun-left, align=left,node font=\ttfamily] {
     parameters:amount \\ 
     body: (if (>= balance amount)\\
      (begin (set! balance\\ (- balance amount))\\
             balance)}
    edge [<-] (fact-iter-fun-left.center); 
  \draw[->] (fact-iter-fun-right.center) -|  (E7-env.south);


\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-10-part-1
[[file:exercise-3-10-part-1.png]]


The second one:
#+begin_src scheme :exports both :results output
  (define (make-withdraw initial-amount)
  (let ((balance initial-amount))
  (lambda (amount)
  (if (>= balance amount)
  (begin (set! balance (- balance amount))
  balance)
  "Insufficient funds"))))
#+end_src

#+name: exercise-3-10-part-2
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-10-part-2.png
\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
     font=\sffamily,pics/two dots/.style={code={
     \node [draw,minimum size=5mm,circle,colored tokens={black!50}] 
     (#1-left) {};
    \node [draw,minimum size=5mm,circle,colored tokens={black!50},
    right=0pt of #1-left]
        (#1-right) {};
    \node [rectangle, fit=(#1-left) (#1-right)] (#1){};
    }},
    every pin edge/.style={<-,very thick},
    box/.style={draw,rectangle,inner sep=#1},box/.default=2mm]

  \node (W1)   {make-withdraw:};
  \node (fake1) [right=100mm of W1] {};  
  \node (fact-iter) [above=3mm of W1.west,anchor=west] {W1:};
%
  \node (g env) [box, fit=(W1) (fake1) (fact-iter),
  pin={[text width=1cm,pin distance=10mm]left:global env}]
  { };

  \path ([yshift=-20mm]W1.east)pic{two dots=w1fun}
    (w1fun) edge [<-, to path={|- (\tikztotarget)}] (W1.east);
  \node [below=of w1fun-left, align=left,font=\ttfamily] 
{\noindent parameters:initial-amount \\ 
body:\\ 
(let ((balance initial-amount))\\
  (lambda (amount)\\
  (if (>= balance amount)\\
  (begin (set! balance\\ (- balance amount))\\
  balance)\\
  "Insufficient funds"))
}
    edge [<-] (w1fun-left.center); 
  \draw[->] (w1fun-right.center) -| ([xshift=3mm] w1fun-right.east |- g env.south);

\path (g env.south west) -- (g env.south east)
node [pos=7/8] (fake2-7) {}
node (E7-env) [below=5mm of fake2-7,box,
    pin={[pin distance=5mm]left:E1},align=left] 
    {initial-amount:100}
    edge [->] (fake2-7) 
node (E2) [below=5mm of E7-env,box,
    pin={[pin distance=5mm]left:E2},align=left] 
    {balance:100}
    edge [->] (E7-env) 

;

\path coordinate[below right=15mm and 40mm of w1fun] (aux)
    (aux) pic{two dots=fact-iter-fun}
    (fact-iter-fun) edge [<-, to path={|- (\tikztotarget)}] (fact-iter.east);
  \node [below=of fact-iter-fun-left, align=left,node font=\ttfamily] {
     parameters:amount \\ 
     body: (if (>= balance amount)\\
      (begin (set! balance\\ (- balance amount))\\
             balance)}
    edge [<-] (fact-iter-fun-left.center); 
  \draw[->] (fact-iter-fun-right.center) -|  (E2);


\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-10-part-2
[[file:exercise-3-10-part-2.png]]

I think these two diagrams explain things quite well. An additional
~let~ creates an additional frame, which is visible on the figure
[[exercise-3-10-part-2]]. 

*** DONE Exercise 3.11 Internal definitions
    CLOSED: [2019-11-26 Tue 12:44]

This is a huge task. Let us first draw ~make-account~, and then
improve on it.

#+name: exercise-3-11-part-1
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-11-part-1.png
  \begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
       font=\sffamily,pics/two dots/.style={code={
       \node [draw,minimum size=5mm,circle,colored tokens={black!50}] 
       (#1-left) {};
      \node [draw,minimum size=5mm,circle,colored tokens={black!50},
      right=0pt of #1-left]
	  (#1-right) {};
      \node [rectangle, fit=(#1-left) (#1-right)] (#1){};
      }},
      every pin edge/.style={<-,very thick},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      node distance=4mm]

    \node (W1)   {make-account:};
    \node (fake1) [right=100mm of W1] {};  
    \node (fact-iter) [above=3mm of W1.west,anchor=west] {acc:};
  %
    \node (g env) [box, fit=(W1) (fake1) (fact-iter),
    pin={[text width=1cm,pin distance=10mm]left:global env}]
    { };

    \path ([yshift=-20mm]W1.east)pic{two dots=w1fun}
      (w1fun) edge [<-, to path={|- (\tikztotarget)}] (W1.east);
    \node [below=5mm of w1fun-left, align=left,font=\ttfamily] 
  {\noindent parameters:\vphantom{d}balance \\ 
  body:\\   
  (define (withdraw amount)\\
  (if (>= balance amount)\\
  (begin (set! balance\\ (- balance amount))\\
  balance)\\
  "Insufficient funds"))\\
  (define (deposit amount)\\
  (set! balance (+ balance amount))\\
  balance)\\
  (define (dispatch m)\\
  (cond ((eq? m 'withdraw) withdraw)\\
  ((eq? m 'deposit) deposit)\\
  (else\\
  (error "Unknown request: MAKE-ACCOUNT"\\
  m))))\\
  dispatch
  }
      edge [<-] (w1fun-left.center); 
    \draw[->] (w1fun-right.center) -| ([xshift=3mm] w1fun-right.east |- g env.south);

  \path (g env.south west) -- (g env.south east)
  node [pos=7/8] (fake2-7) {}
  node (balance-var)  [below=6mm of fake2-7] {\vphantom{l}balance:30}
  node (withdraw-var) [below=of balance-var.west,anchor=west] {\vphantom{l}withdraw:}
  node (deposit-var)  [below=of withdraw-var.west,anchor=west] {\vphantom{l}deposit:}
  node (E7-env) [box,
      pin={[pin distance=5mm]left:E1},align=left,
      fit=(balance-var) (deposit-var) (withdraw-var)] 
      {}
  edge [->] (fake2-7) ;

  \path coordinate[below right=5mm and 40mm of w1fun] (aux)
      (aux) pic{two dots=fact-iter-fun}
      (fact-iter-fun) edge [<-, to path={|- (\tikztotarget)}] (fact-iter.east);
  \node [below=5mm of fact-iter-fun-left, align=left,node font=\ttfamily] {
       parameters:m \\ 
       body: (cond ((eq? m 'withdraw) withdraw)\\
	     ((eq? m 'deposit) deposit)\\
	     (else\\
	     (error "Unknown request: MAKE-ACCOUNT"\\
	     m)))
      }
   edge [<-] (fact-iter-fun-left.center); 
  \draw[->] (fact-iter-fun-right.center) -|  ($ (E7-env.south) - (5mm,0mm) $);
  
  \path coordinate[below right=10mm and 13mm of E7-env.south] (aux)
      (aux) pic{two dots=deposit}
      (deposit) edge [<-, to path={|- (\tikztotarget)}] (deposit-var.east);
  \node [below=5mm of deposit-left, align=left,node font=\ttfamily] {
       parameters:amount \\ 
       body:  (set! balance\\ (+ balance amount))\\
              balance
      }
   edge [<-] (deposit-left.center); 
  \draw[->] (deposit-right.center) |- (fact-iter-fun -| E7-env.south) -|  ($ (E7-env.south) - (0mm,0mm) $);

  \path coordinate[below right=10mm and 50mm of E7-env.south] (aux)
      (aux) pic{two dots=withdraw}
      (withdraw) edge [<-, to path={|- (\tikztotarget)}] (withdraw-var.east);
  \node [below=5mm of withdraw-left, align=left,node font=\ttfamily] {
       parameters:amount \\ 
       body:  (set! balance\\ (- balance amount))\\
              balance
      }
   edge [<-] (withdraw-left.center); 
  \draw[->] (withdraw-right.center) |-  ($ (E7-env.east) + (0mm,5mm) $);

  \end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-11-part-1
[[file:exercise-3-11-part-1.png]]

I am not plotting the intermediate environments, that is too much
work, but the important thing is that when ~acc~ is evaluated, the
evaluation frame is appended to the environment E1, and the lookup is
performed in the enclosing environment, including the bindings for
~dispatch~ and ~withdraw~. 

The state for ~acc~ is kept in the environment E1. 

If we to define ~acc2~, the frame in which we define it would mean a
lot. Let us assume that we define ~acc2~ at the top level. This would
mean that now we would have two environments, E1 and E2 pointing, both
the children of the global environment. Only the global definitions
(that is ~make-account~, ~acc1~ and ~acc2~) would be shared. 

*** DONE Exercise 3.12 Drawing ~append!~
    CLOSED: [2019-11-29 Fri 11:55]

Now we need to draw box-and-pointer diagrams for the two variants of ~append~.

The first ~append~ can be drawn like this:

#+name: exercise-3-12-part1
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-12-part1.png

\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
      font=\sffamily,
      node distance=20mm,
      pics/cons cell/.style n args={3}{code={
      \coordinate (origin);
      \node[anchor=east,minimum size=10mm,inner sep=0] (#1-car) at(0,0) {};
      \node[anchor=west,minimum size=10mm,inner sep=0] (#1-cdr) at(0,0) {};
      \node[name=#1-box,fit=(#1-car) (#1-cdr),draw,shape=rectangle,rounded
 corners=0.5mm]  {};
      \draw[shorten <=1pt, shorten >=1pt] (#1-box.south -| origin) -- (#1-box.north -| origin);
      \if#2t
      % \path node[shape=circle,fill,draw,radius=2mm] at (#1-car.center) {};
      \filldraw (#1-car.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten <=1pt] (#1-car.south west) to (#1-car.north east);
      \fi
      \if#3t
      \filldraw (#1-cdr.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten >=1pt] (#1-cdr.south west) to (#1-cdr.north east);
      \fi
      }},
      pics/cons element/.style n args={2}{code={
      \node [minimum size=10mm,inner sep=0,rounded corners=1mm, draw, shape=rectangle] (#1) {#2};
      }},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      ]
\node (x) {x};
\node[right=200mm of x] {};
\pic[right=of x] {cons cell={cell-a}{t}{t}};
\draw[->] (x) to (cell-a-box);
\pic[below=of cell-a-car] {cons element={a}{a}};
\pic[right=of cell-a-cdr] {cons cell={cell-b}{t}{f}};
\pic[below=of cell-b-car] {cons element={b}{b}};
\draw[->] (cell-a-cdr.center) to (cell-b-box);
\draw[->] (cell-a-car.center) to (a);
\draw[->] (cell-b-car.center) to (b);

\node[right=of cell-b-box] (y) {y};
\pic[right=of y] {cons cell={cell-c}{t}{t}};
\draw[->] (y) to (cell-c-box);
\pic[below=of cell-c-car] {cons element={c}{c}};
\pic[right=of cell-c-cdr] {cons cell={cell-d}{t}{f}};
\pic[below=of cell-d-car] {cons element={d}{d}};
\draw[->] (cell-c-cdr.center) to (cell-d-box);
\draw[->] (cell-c-car.center) to (c);
\draw[->] (cell-d-car.center) to (d);

\node[below=50mm of x] (z) {z};
\pic[right=of z] {cons cell={cell-a-2}{t}{t}};
\draw[->] (z) to (cell-a-2-box);
\pic[below=of cell-a-2-car] {cons element={a2}{a}};
\pic[right=of cell-a-2-cdr] {cons cell={cell-b-2}{t}{t}};
\pic[below=of cell-b-2-car] {cons element={b2}{b}};
\pic[right=of cell-b-2-cdr] {cons cell={cell-c-2}{t}{t}};
\pic[below=of cell-c-2-car] {cons element={c2}{c}};
\pic[right=of cell-c-2-cdr] {cons cell={cell-d-2}{t}{f}};
\pic[below=of cell-d-2-car] {cons element={d2}{d}};


\draw[->] (cell-a-2-cdr.center) to (cell-b-2-box);
\draw[->] (cell-a-2-car.center) to (a2);
\draw[->] (cell-b-2-car.center) to (b2);
\draw[->] (cell-b-2-cdr.center) to (cell-c-2-box);
\draw[->] (cell-c-2-car.center) to (c2);
\draw[->] (cell-c-2-cdr.center) to (cell-d-2-box);
\draw[->] (cell-d-2-car.center) to (d2);


\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-12-part1
[[file:exercise-3-12-part1.png]]



#+begin_src scheme :exports both :results value
?
(define x (list 'a 'b))
(define y (list 'c 'd))
(define z (append x y))
z
(cdr x)

#+end_src

#+RESULTS:
| b |


The second append, done with ~append!~ , modifies ~x~.

#+name: exercise-3-12-part2
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-12-part2.png

\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
      font=\sffamily,
      node distance=20mm,
      pics/cons cell/.style n args={3}{code={
      \coordinate (origin);
      \node[anchor=east,minimum size=10mm,inner sep=0] (#1-car) at(0,0) {};
      \node[anchor=west,minimum size=10mm,inner sep=0] (#1-cdr) at(0,0) {};
      \node[name=#1-box,fit=(#1-car) (#1-cdr),draw,shape=rectangle,rounded
 corners=0.5mm]  {};
      \draw[shorten <=1pt, shorten >=1pt] (#1-box.south -| origin) -- (#1-box.north -| origin);
      \if#2t
      % \path node[shape=circle,fill,draw,radius=2mm] at (#1-car.center) {};
      \filldraw (#1-car.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten <=1pt] (#1-car.south west) to (#1-car.north east);
      \fi
      \if#3t
      \filldraw (#1-cdr.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten >=1pt] (#1-cdr.south west) to (#1-cdr.north east);
      \fi
      }},
      pics/cons element/.style n args={2}{code={
      \node [minimum size=10mm,inner sep=0,rounded corners=1mm, draw, shape=rectangle] (#1) {#2};
      }},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      ]
\node (x) {x};
\node[right=200mm of x] {};
\pic[right=of x] {cons cell={cell-a}{t}{t}};
\draw[->] (x) to (cell-a-box);
\pic[below=of cell-a-car] {cons element={a}{a}};
\pic[right=of cell-a-cdr] {cons cell={cell-b}{t}{t}};
\pic[below=of cell-b-car] {cons element={b}{b}};
\draw[->] (cell-a-cdr.center) to (cell-b-box);
\draw[->] (cell-a-car.center) to (a);
\draw[->] (cell-b-car.center) to (b);

\node[right=of cell-b-box] (y) {y};
\pic[right=of y] {cons cell={cell-c}{t}{t}};
\draw[->] (y) to (cell-c-box);
\pic[below=of cell-c-car] {cons element={c}{c}};
\pic[right=of cell-c-cdr] {cons cell={cell-d}{t}{f}};
\pic[below=of cell-d-car] {cons element={d}{d}};
\draw[->] (cell-c-cdr.center) to (cell-d-box);
\draw[->] (cell-c-car.center) to (c);
\draw[->] (cell-d-car.center) to (d);
%\draw (cell-b-cdr.center) -- controls (5cm,1cm) and (6cm,1cm) -- (cell-c-box.center);
\draw[->] (cell-b-cdr.center) .. controls ($ (y.north) + (0,5mm) $) .. (cell-c-box);

\node[above=of cell-a-car] (w) {w};
\draw[->] (w) to (cell-a-car);

\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-12-part2
[[file:exercise-3-12-part2.png]]


Therefore, the answer is the following:
#+begin_src scheme :exports both :results value
<<last-pair>>
(define (append! x y)
(set-cdr! (last-pair x) y)
x)

(define x (list 'a 'b))
(define y (list 'c 'd))
(define w (append! x y))
w
(cdr x)
#+end_src

#+RESULTS:
| b | c | d |

*** DONE Exercise 3.13 ~make-cycle~
    CLOSED: [2019-11-29 Fri 12:09]

This thing is called a "circular list".

#+begin_src scheme :exports both :results value
<<last-pair>>
(define (make-cycle x)
(set-cdr! (last-pair x) x)
x)
(define z (make-cycle (list 'a 'b 'c)))
z

#+end_src

#+RESULTS:
: (a b c...

#+name: exercise-3-13
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-12.png

\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
      font=\sffamily,
      node distance=20mm,
      pics/cons cell/.style n args={3}{code={
      \coordinate (origin);
      \node[anchor=east,minimum size=10mm,inner sep=0] (#1-car) at(0,0) {};
      \node[anchor=west,minimum size=10mm,inner sep=0] (#1-cdr) at(0,0) {};
      \node[name=#1-box,fit=(#1-car) (#1-cdr),draw,shape=rectangle,rounded
 corners=0.5mm]  {};
      \draw[shorten <=1pt, shorten >=1pt] (#1-box.south -| origin) -- (#1-box.north -| origin);
      \if#2t
      % \path node[shape=circle,fill,draw,radius=2mm] at (#1-car.center) {};
      \filldraw (#1-car.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten <=1pt] (#1-car.south west) to (#1-car.north east);
      \fi
      \if#3t
      \filldraw (#1-cdr.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten >=1pt] (#1-cdr.south west) to (#1-cdr.north east);
      \fi
      }},
      pics/cons element/.style n args={2}{code={
      \node [minimum size=10mm,inner sep=0,rounded corners=1mm, draw, shape=rectangle] (#1) {#2};
      }},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      ]
\node (z) {z};
\node[right=200mm of z] {};
\pic[right=of z] {cons cell={cell-a}{t}{t}};
\draw[->] (z) to (cell-a-box);
\pic[below=of cell-a-car] {cons element={a}{a}};
\pic[right=of cell-a-cdr] {cons cell={cell-b}{t}{t}};
\pic[below=of cell-b-car] {cons element={b}{b}};
\draw[->] (cell-a-cdr.center) to (cell-b-box);
\draw[->] (cell-a-car.center) to (a);
\draw[->] (cell-b-car.center) to (b);
\pic[right=of cell-b-box] {cons cell={cell-c}{t}{t}};
\pic[below=of cell-c-car] {cons element={c}{c}};
\draw[->] (cell-c-car.center) to (c);
\draw[->] (cell-b-cdr.center) to (cell-c-box);
\draw[->] (cell-c-cdr.center) .. controls ($ (cell-c-cdr.center) + (0,30mm) $)
and ($ (cell-a-car.center) + (0,30mm) $) .. (cell-a-car);

\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-13
[[file:exercise-3-12.png]]

*** DONE Exercise 3.14 ~mystery~
    CLOSED: [2019-11-29 Fri 21:23]

#+begin_src scheme :exports both :results output
  (define (mystery x)
    (define (loop x y)
      (if (null? x)
	  y
	  (let ((temp (cdr x)))
	    (set-cdr! x y)
	    (loop temp x))))
    (loop x '()))
(define v (list 'a 'b 'c 'd))
(show #t "initial v: " v "\n")
(define w (mystery v))
(show #t "w: " w "\n")
(show #t "what remains of v: " v "\n")
#+end_src

#+RESULTS:
: Initial v: (a b c d)
: w: (d c b a)
: what remains of v: (a)

The ~mystery~ procedure is roughly equivalent to ~(reverse x)~, except
that it works in constant space, whereas an ordinary ~reverse~
additionally uses as much space as ~x~ occupies.

Let us plot ~v~ before the operation.

#+name: exercise-3-14-part1
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-14-part1.png

\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
      font=\sffamily,
      node distance=20mm,
      pics/cons cell/.style n args={3}{code={
      \coordinate (origin);
      \node[anchor=east,minimum size=10mm,inner sep=0] (#1-car) at(0,0) {};
      \node[anchor=west,minimum size=10mm,inner sep=0] (#1-cdr) at(0,0) {};
      \node[name=#1-box,fit=(#1-car) (#1-cdr),draw,shape=rectangle,rounded
 corners=0.5mm]  {};
      \draw[shorten <=1pt, shorten >=1pt] (#1-box.south -| origin) -- (#1-box.north -| origin);
      \if#2t
      \filldraw (#1-car.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten <=1pt] (#1-car.south west) to (#1-car.north east);
      \fi
      \if#3t
      \filldraw (#1-cdr.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten >=1pt] (#1-cdr.south west) to (#1-cdr.north east);
      \fi
      }},
      pics/cons element/.style n args={2}{code={
      \node [minimum size=10mm,inner sep=0,rounded corners=1mm, draw, shape=rectangle] (#1) {#2};
      }},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      ]

\node (v) {v};
\pic[right=of v] {cons cell={cell-a-2}{t}{t}};
\draw[->] (v) to (cell-a-2-box);
\pic[below=of cell-a-2-car] {cons element={a2}{a}};
\pic[right=of cell-a-2-cdr] {cons cell={cell-b-2}{t}{t}};
\pic[below=of cell-b-2-car] {cons element={b2}{b}};
\pic[right=of cell-b-2-cdr] {cons cell={cell-c-2}{t}{t}};
\pic[below=of cell-c-2-car] {cons element={c2}{c}};
\pic[right=of cell-c-2-cdr] {cons cell={cell-d-2}{t}{f}};
\pic[below=of cell-d-2-car] {cons element={d2}{d}};


\draw[->] (cell-a-2-cdr.center) to (cell-b-2-box);
\draw[->] (cell-a-2-car.center) to (a2);
\draw[->] (cell-b-2-car.center) to (b2);
\draw[->] (cell-b-2-cdr.center) to (cell-c-2-box);
\draw[->] (cell-c-2-car.center) to (c2);
\draw[->] (cell-c-2-cdr.center) to (cell-d-2-box);
\draw[->] (cell-d-2-car.center) to (d2);


\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-14-part1
[[file:exercise-3-14.png]]


~mystery~ reverses the list, so the diagram would be:

#+name: exercise-3-14-part2
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-14-part2.png

\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
      font=\sffamily,
      node distance=20mm,
      pics/cons cell/.style n args={3}{code={
      \coordinate (origin);
      \node[anchor=east,minimum size=10mm,inner sep=0] (#1-car) at(0,0) {};
      \node[anchor=west,minimum size=10mm,inner sep=0] (#1-cdr) at(0,0) {};
      \node[name=#1-box,fit=(#1-car) (#1-cdr),draw,shape=rectangle,rounded
 corners=0.5mm]  {};
      \draw[shorten <=1pt, shorten >=1pt] (#1-box.south -| origin) -- (#1-box.north -| origin);
      \if#2t
      \filldraw (#1-car.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten <=1pt] (#1-car.south west) to (#1-car.north east);
      \fi
      \if#3t
      \filldraw (#1-cdr.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten >=1pt] (#1-cdr.south west) to (#1-cdr.north east);
      \fi
      }},
      pics/cons element/.style n args={2}{code={
      \node [minimum size=10mm,inner sep=0,rounded corners=1mm, draw, shape=rectangle] (#1) {#2};
      }},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      ]

\node (w) {w};
\pic[right=of w] {cons cell={cell-a-2}{t}{t}};
\draw[->] (w) to (cell-a-2-box);
\pic[below=of cell-a-2-car] {cons element={a2}{d}};
\pic[right=of cell-a-2-cdr] {cons cell={cell-b-2}{t}{t}};
\pic[below=of cell-b-2-car] {cons element={b2}{c}};
\pic[right=of cell-b-2-cdr] {cons cell={cell-c-2}{t}{t}};
\pic[below=of cell-c-2-car] {cons element={c2}{b}};
\pic[right=of cell-c-2-cdr] {cons cell={cell-d-2}{t}{f}};
\pic[below=of cell-d-2-car] {cons element={d2}{a}};


\draw[->] (cell-a-2-cdr.center) to (cell-b-2-box);
\draw[->] (cell-a-2-car.center) to (a2);
\draw[->] (cell-b-2-car.center) to (b2);
\draw[->] (cell-b-2-cdr.center) to (cell-c-2-box);
\draw[->] (cell-c-2-car.center) to (c2);
\draw[->] (cell-c-2-cdr.center) to (cell-d-2-box);
\draw[->] (cell-d-2-car.center) to (d2);

\node[above=of cell-d-2-car] (v) {v};
\draw[->] (v) to (cell-d-2-car);

\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-14-part2
[[file:exercise-3-14-part2.png]]

~v~ still points to the cell containing ~'x~, but now the ~car~ of
this cell is an empty list.

*** DONE Exercise 3.15 ~set-to-wow!~
    CLOSED: [2019-12-01 Sun 19:59]

#+begin_src scheme :exports both :results output
(define (set-to-wow! x) 
   (set-car! (car x) 'wow)
    x)
(define x (list 'a 'b))
(define z1 (cons x x))
(define z2 (cons (list 'a 'b) (list 'a 'b)))
(show #t "The structures are: \n" z1 "\n" z2 "\n")
(set-to-wow! z1)
(show #t "Modified z1: " z1 "\n")
(set-to-wow! z2)
(show #t "Modifier z2: " z2 "\n")
#+end_src

#+RESULTS:
: The structures are: 
: ((a b) a b)
: ((a b) a b)
: Modified z1: ((wow b) wow b)
: Modifier z2: ((wow b) a b)

First let us draw ~z1~ after ~set-to-wow!~.

#+name: exercise-3-15-part1
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc,graphs}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-15-part1.png

\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
      font=\sffamily,
      node distance=20mm,
      pics/cons cell/.style n args={3}{code={
      \coordinate (origin);
      \node[anchor=east,minimum size=10mm,inner sep=0] (#1!car) at(0,0) {};
      \node[anchor=west,minimum size=10mm,inner sep=0] (#1!cdr) at(0,0) {};
      \node[name=#1!box,fit=(#1!car) (#1!cdr),draw,shape=rectangle,rounded
 corners=0.5mm]  {};
      \draw[shorten <=1pt, shorten >=1pt] (#1!box.south -| origin) -- (#1!box.north -| origin);
      \if#2t
      \filldraw (#1!car.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten <=1pt] (#1!car.south west) to (#1!car.north east);
      \fi
      \if#3t
      \filldraw (#1!cdr.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten >=1pt] (#1!cdr.south west) to (#1!cdr.north east);
      \fi
      }},
      pics/cons element/.style n args={2}{code={
      \node [minimum size=10mm,inner sep=0,rounded corners=1mm, draw, shape=rectangle] (#1) {#2};
      }},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      ]

\matrix[row sep=10mm,column sep=20mm] {

\node (z1!var) {z1}; & \pic{cons cell={z1}{t}{t}}; &  \\
\node (x) {x};   & \pic{cons cell={list1}{t}{t}}; & \pic{cons cell={list2}{t}{f}}; \\
                 & \pic[below=5mm of list1!car]{cons element={a}{wow}}; & \pic[below=5mm of list2!car]{cons element={b}{b}};\\
};

\node[right=200mm of z1!var] {};

\graph[use existing nodes]
{
z1!var -> z1!box ;
z1!car.center -> list1!car;
z1!cdr.center -> list1!cdr;
list1!cdr.center -> list2!box;
list1!car.center -> a;
list2!car.center -> b;
x -> list1!box;
};
%\draw[->] (z1-var) -- (x);
\end{tikzpicture}


#+end_src

#+RESULTS: exercise-3-15-part1
[[file:exercise-3-15-part1.png]]

Next we shall plot ~z2~ after ~set-to-wow!~.

#+name: exercise-3-15-part2
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc,graphs}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-15-part2.png

\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
      font=\sffamily,
      node distance=20mm,
      pics/cons cell/.style n args={3}{code={
      \coordinate (origin);
      \node[anchor=east,minimum size=10mm,inner sep=0] (#1!car) at(0,0) {};
      \node[anchor=west,minimum size=10mm,inner sep=0] (#1!cdr) at(0,0) {};
      \node[name=#1!box,fit=(#1!car) (#1!cdr),draw,shape=rectangle,rounded
 corners=0.5mm]  {};
      \draw[shorten <=1pt, shorten >=1pt] (#1!box.south -| origin) -- (#1!box.north -| origin);
      \if#2t
      \filldraw (#1!car.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten <=1pt] (#1!car.south west) to (#1!car.north east);
      \fi
      \if#3t
      \filldraw (#1!cdr.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten >=1pt] (#1!cdr.south west) to (#1!cdr.north east);
      \fi
      }},
      pics/cons element/.style n args={2}{code={
      \node [minimum size=10mm,inner sep=0,rounded corners=1mm, draw, shape=rectangle] (#1) {#2};
      }},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      ]

\matrix[row sep=20mm,column sep=20mm] {
                     & \pic[xshift=-5mm]{cons element={wow}{wow}};   & \\
\node (z2!var) {z2}; & \pic{cons cell={z21}{t}{t}}; & \pic{cons cell={z22}{t}{f}}; \\
                     & \pic[xshift=-5mm]{cons element={a}{a}};   & \pic[xshift=-5mm]{cons element={b}{b}}; \\
                     & \pic{cons cell={z23}{t}{t}}; & \pic{cons cell={z24}{t}{f}};\\
};

\node[right=200mm of z2!var] {};

\graph[use existing nodes]
{
z2!var -> z21!box ;
z21!car.center -> wow;
z21!cdr.center -> z22!box;
z22!car.center -> b;
z23!car.center -> a;
z23!cdr.center -> z24!box;
z24!car.center -> b;
};
%\draw[->] (z1-var) -- (x);
\end{tikzpicture}


#+end_src

#+RESULTS: exercise-3-15-part2
[[file:exercise-3-15-part2.png]]


The picture should explain the result of ~set-to-wow!~ fairly well.

*** DONE Exercise 3.16 ~count-pairs~
    CLOSED: [2019-12-02 Mon 00:05]
#+begin_src scheme :exports both :results output
(define (count-pairs x)
(if (not (pair? x))
0
(+ (count-pairs (car x))
(count-pairs (cdr x))
1)))
(show #t "Return three: " (count-pairs (list 'a 'b 'c)) "\n")
(show #t "Return four: " (count-pairs (let ((x (list 'a 'b 'c)))
                          (set-car! (cdr x) (cddr x)) x)) "\n")
(show #t "Return seven: " (count-pairs (let ((x (list 'a 'b 'c)))
                          (set-car!  x (cdr x))
                          (set-car!  (cdr x) (cddr x))    
                          x)) "\n")
 (show #t "Never return: " 
          (let ((x (list 'a 'b 'c)))
             (set-cdr! (cddr x) x)
            x) "\n")

#+end_src

#+RESULTS:
: Return three: 3
: Return four: 4
: Return seven: 7
: Never return: #0=(a b c . #0#)

#+name: exercise-3-16
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc,graphs}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-16.png

\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
      font=\sffamily,
      node distance=20mm,
      pics/cons cell/.style n args={3}{code={
      \coordinate (origin);
      \node[anchor=east,minimum size=10mm,inner sep=0] (#1!car) at(0,0) {};
      \node[anchor=west,minimum size=10mm,inner sep=0] (#1!cdr) at(0,0) {};
      \node[name=#1!box,fit=(#1!car) (#1!cdr),draw,shape=rectangle,rounded
 corners=0.5mm]  {};
      \draw[shorten <=1pt, shorten >=1pt] (#1!box.south -| origin) -- (#1!box.north -| origin);
      \if#2t
      % \path node[shape=circle,fill,draw,radius=2mm] at (#1-car.center) {};
      \filldraw (#1!car.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten <=1pt] (#1!car.south west) to (#1!car.north east);
      \fi
      \if#3t
      \filldraw (#1!cdr.center) circle[radius=0.66mm] ;
      \else
      \draw[shorten >=1pt] (#1!cdr.south west) to (#1!cdr.north east);
      \fi
      }},
      pics/cons element/.style n args={2}{code={
      \node [xshift=-5mm,minimum size=10mm,inner sep=0,rounded corners=1mm, draw, shape=rectangle] (#1) {#2};
      }},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      ]
\matrix[row sep=10mm,column sep=20mm] {
\pic{cons cell={cell1}{t}{t}}; & \pic{cons cell={cell2}{t}{t}}; & \pic{cons cell={cell3}{t}{f}}; \\
\pic{cons element={a}{a}};     & \pic{cons element={b}{b}};     & \pic{cons element={c}{d}}; \\
\pic{cons cell={cell4}{t}{t}}; & \pic{cons cell={cell5}{t}{t}}; & \pic{cons cell={cell6}{t}{f}}; \\
\pic{cons element={a2}{a}};    &                                & \pic{cons element={c2}{c}}; \\
\pic{cons cell={cell7}{t}{t}}; & \pic{cons cell={cell8}{t}{t}}; & \pic{cons cell={cell9}{t}{f}}; \\
                               &                                & \pic{cons element={c3}{c}}; \\
\pic{cons cell={cell10}{t}{t}}; & \pic{cons cell={cell11}{t}{t}}; & \pic{cons cell={cell12}{t}{t}}; \\
\pic{cons element={a4}{a}};     & \pic{cons element={b4}{b}};     & \pic{cons element={c4}{d}}; \\
};
\node[right=200mm of cell1!box] {};

\graph[use existing nodes,
skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
{
cell1!cdr.center -> cell2!box;
cell1!car.center -> a;
cell2!car.center -> b;
cell2!cdr.center -> cell3!box;
cell3!car.center -> c;
cell4!cdr.center -> cell5!box;
cell4!car.center -> a2;
cell5!car.center ->[skip loop=10mm] cell6!car;
cell5!cdr.center -> cell6!box;
cell6!car.center -> c2;
cell7!cdr.center -> cell8!box;
cell7!car.center ->[skip loop=-10mm] cell8!car;
cell8!cdr.center -> cell9!box;
cell8!car.center ->[skip loop=10mm] cell9!car;
cell9!car.center -> c3;
cell10!car.center -> a4;
cell10!cdr.center -> cell11!box;
cell11!car.center -> b4;
cell11!cdr.center -> cell12!box;
cell12!car.center -> c4;
cell12!cdr.center ->[skip loop=10mm] cell10!car;
};

\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-16
[[file:exercise-3-16.png]]
*** DONE Exercise 3.17 Real ~count-pairs~
    CLOSED: [2019-12-02 Mon 00:47]

This is an inefficient solution, because it uses an O(n) lookup. 

#+begin_src scheme :exports both :results output
      (define (count-pairs s)
	(define my-set (list))
	(define (count-pairs-loop x)
	   (cond ((not (pair? x)) 0)
		 ((memq x my-set) 0)
		 (else (begin
			 (set! my-set (append my-set (list x)))
			 (+ (count-pairs-loop (car x))
			    (count-pairs-loop (cdr x))
			    1)))))
	(set! my-set (list))
	(count-pairs-loop s))
    (show #t "Returned three: " (count-pairs (list 'a 'b 'c)) "\n")
    (show #t "Returned four: " (count-pairs (let ((x (list 'a 'b 'c)))
			      (set-car! (cdr x) (cddr x)) x)) "\n")
    (show #t "Returned seven: " (count-pairs (let ((x (list 'a 'b 'c)))
			      (set-car!  x (cdr x))
			      (set-car!  (cdr x) (cddr x))    
			      x)) "\n")
    (show #t "Never returned: " 
	      (count-pairs (let ((x (list 'a 'b 'c)))
		 (set-cdr! (cddr x) x)
		x)) "\n")

#+end_src

#+RESULTS:
: Returned three: 3
: Returned four: 3
: Returned seven: 3
: Never returned: 3

*** DONE Exercise 3.18 Finding cycles
    CLOSED: [2019-12-02 Mon 01:04]

Still not a very efficient solution, but it works.

#+begin_src scheme :exports both :results output
  (define (is-cyclic? y)
    (define seen-elements (list))
    (define (is-s-l x)
      (cond ((not (pair? x)) #f)
	    ((null? x) #f)
	    ((memq x seen-elements) #t)
	    (else (begin
		    (set! seen-elements (append seen-elements (list x)))
		    (is-s-l (cdr x))))))
    (set! seen-elements (list))
    (is-s-l y))
  (show #t "Returned three: " (is-cyclic? (list 'a 'b 'c)) "\n")
  (show #t "Returned four: " (is-cyclic? (let ((x (list 'a 'b 'c)))
					   (set-car! (cdr x) (cddr x)) x)) "\n")
  (show #t "Returned seven: " (is-cyclic? (let ((x (list 'a 'b 'c)))
					    (set-car!  x (cdr x))
					    (set-car!  (cdr x) (cddr x))    
					    x)) "\n")
  (show #t "Never returned: " 
	(is-cyclic? (let ((x (list 'a 'b 'c)))
		      (set-cdr! (cddr x) x)
		      x)) "\n")

#+end_src

#+RESULTS:
: Returned three: #f
: Returned four: #f
: Returned seven: #f
: Never returned: #t

*** DONE Exercise 3.19 Efficient finding cycles
    CLOSED: [2019-12-02 Mon 23:29]

The idea that we are going to explore in this exercise is slightly
similar to the dynamic programming. This will not be efficient at all,
but will eventually find not just whether the list has a cycle, but
also the length of the cycle.

#+begin_src scheme :exports both :results output
    (define (is-cyclic? l)
      (let loop ((starting-elem 0)
		 (cycle-len 1))
	(cond ((or (not (pair? (drop l starting-elem)))
		  (not (pair? (drop l (+ starting-elem cycle-len))))) 
	       #f)
	      ((eq?  (drop l starting-elem) 
		     (drop l (+ starting-elem cycle-len))) #t)
	      ((> starting-elem 0) (loop (- starting-elem 1) (+ cycle-len 1)))
	      (else (loop cycle-len 1)))))

    (show #t "Returned three: " (is-cyclic? (list 'a 'b 'c)) "\n")
    (show #t "Returned four: " (is-cyclic? (let ((x (list 'a 'b 'c)))
					     (set-car! (cdr x) (cddr x)) x)) "\n")
    (show #t "Returned seven: " (is-cyclic? (let ((x (list 'a 'b 'c)))
					      (set-car!  x (cdr x))
					      (set-car!  (cdr x) (cddr x))    
					      x)) "\n")
    (show #t "Never returned: " 
	  (is-cyclic? (let ((x (list 'a 'b 'c)))
			(set-cdr! (cddr x) x)
			x)) "\n")

#+end_src

#+RESULTS:
: Returned three: #f
: Returned four: #f
: Returned seven: #f
: Never returned: #t

The not very clever idea used here is that we can check if an element
~x~ is a start of a loop of length ~n~. Therefore we can iterate over
all possible values of ~x~ and ~n~. This exercise uses the ~(scheme
list)~ standard library from R7RS.

This algorithm clearly only uses O(1) memory, since we only remember
the number of the starting element and the cycle length.

*** DONE Exercise 3.20 Procedural ~set-car!~
    CLOSED: [2019-12-03 Tue 14:40]

I am excluding the definitions from the diagram, they are cumbersome.

#+name: exercise-3-20
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-20.png
  \begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
       font=\sffamily,pics/two dots/.style={code={
       \node [draw,minimum size=5mm,circle,colored tokens={black!50}] 
       (#1-left) {};
      \node [draw,minimum size=5mm,circle,colored tokens={black!50},
      right=0pt of #1-left]
	  (#1-right) {};
      \node [rectangle, fit=(#1-left) (#1-right)] (#1){};
      }},
      every pin edge/.style={<-,very thick},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      node distance=4mm]



    \node (x-global)  {x:};
    \node (fake1) [right=100mm of x-global] {};  
    \node (z-global) [above=3mm of x-global.west,anchor=west] {z:};
  %
    \node (g env) [box, fit=(z-global) (fake1) (x-global),
    pin={[text width=1cm,pin distance=10mm]left:global env}]
    { };

  \path (g env.south west) -- (g env.south east)
  node [pos=2/8] (fake2-7) {}
  node (x-var)  [below=6mm of fake2-7] {\vphantom{l}x:17}
  node (y-var) [below=of x-var.west,anchor=west] {\vphantom{l}y:2}
  node (setx1) [below=of y-var.west,anchor=west] {\vphantom{l}set-x!: ...}
  node (sety1) [below=of setx1.west,anchor=west] {\vphantom{l}set-y!: ...}
  node (E1-env) [box,
      pin={[pin distance=5mm]left:E1},align=left,
      fit=(x-var) (y-var) (setx1) (sety1)] 
      {}
  edge [->] (g env.south -| E1-env.north) ;

  \path (g env.south west) -- (g env.south east)
  node[pos=1/16] (anchor1)
  coordinate[below=50 mm of anchor1] (aux)
      (aux) pic{two dots=x-dispatch}
      (x-dispatch) edge [<-, to path={|- (\tikztotarget)}] (x-global.east);
  \draw[->] (x-dispatch-right.center) -|  (E1-env.south);
  \node [below=5mm of x-dispatch-left, align=left,font=\ttfamily] 
  {\noindent parameters:\vphantom{l}m \\ 
  body:\\   
(cond \\ ((eq? m 'car) x) \\
((eq? m 'cdr) y) \\
((eq? m 'set-car!) set-x!) \\
((eq? m 'set-cdr!) set-y!) \\
(else \\
(error "Undefined operation: CONS" m))) \\
  }
      edge [<-] (x-dispatch-left.center);

  \path (g env.south west) -- (g env.south east)
  node [pos=9/16] (fake-8) {}
  node (x-var)  [below=6mm of fake-8] {\vphantom{l}x:}
  node (y-var) [below=of x-var.west,anchor=west] {\vphantom{l}y:}
  node (setx1) [below=of y-var.west,anchor=west] {\vphantom{l}set-x!: ...}
  node (sety1) [below=of setx1.west,anchor=west] {\vphantom{l}set-y!: ...}
  node (E2-env) [box,
      pin={[pin distance=5mm]left:E2},align=left,
      fit=(x-var) (y-var) (setx1) (sety1)] 
      {}
  edge [->] (g env.south -| E2-env.north) ;
  \draw[->] (x-var.east)  ++(1mm,0) -- ++(0,5mm) -| ($ (x-dispatch.north) + (1mm,0) $);
  \draw[->] (y-var.east) -- ++(0,6mm) -| ($ (x-dispatch.north) + (2mm,0) $);

  \path (g env.south west) -- (g env.south east)
  node[pos=12/16] (anchor)
  coordinate[below=50 mm of anchor] (aux)
      (aux) pic{two dots=z-dispatch}
      (z-dispatch) edge [<-, to path={|- (\tikztotarget)}] (z-global.east);
  \draw[->] (z-dispatch-right.center) -- ++(0,7mm) -|  (E2-env.south);
  \node [below=5mm of z-dispatch-left, align=left,font=\ttfamily] 
  {\noindent parameters:\vphantom{l}m \\ 
  body:\\   
(cond \\ ((eq? m 'car) x) \\
((eq? m 'cdr) y) \\
((eq? m 'set-car!) set-x!) \\
((eq? m 'set-cdr!) set-y!) \\
(else \\
(error "Undefined operation: CONS" m))) \\
  }
      edge [<-] (z-dispatch-left.center);


  \end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-20
[[file:exercise-3-20.png]]

I am only drawing the final environment, but the idea should be quite obvious.

*** DONE Exercise 3.21 queues
    CLOSED: [2019-12-03 Tue 15:10]

#+begin_src scheme :exports both :results output :noweb-ref queue
  (define (front-ptr queue) (car queue))
  (define (rear-ptr queue)
    (cdr queue))
  (define (set-front-ptr! queue item)
    (set-car! queue item))
  (define (set-rear-ptr! queue item)
    (set-cdr! queue item))
  (define (empty-queue? queue)
    (null? (front-ptr queue)))
  (define (make-queue) (cons '() '()))
  (define (front-queue queue)
    (if (empty-queue? queue)
	(error "FRONT called with an empty queue" queue)
	(car (front-ptr queue))))
  (define (insert-queue! queue item)
    (let ((new-pair (cons item '())))
      (cond ((empty-queue? queue)
	     (set-front-ptr! queue new-pair)
	     (set-rear-ptr! queue new-pair)
	     queue)
	    (else
	     (set-cdr! (rear-ptr queue) new-pair)
	     (set-rear-ptr! queue new-pair)
	     queue))))
  (define (delete-queue! queue)
    (cond ((empty-queue? queue)
	   (error "DELETE! called with an empty queue" queue))
	  (else (set-front-ptr! queue (cdr (front-ptr queue)))
		queue)))
#+end_src

#+begin_src scheme :exports both :results output
<<queue>>
(define q1 (make-queue))
(show #t "(insert-queue! q1 'a) = " (insert-queue! q1 'a) "\n")
(show #t "(insert-queue! q1 'b) = " (insert-queue! q1 'b) "\n")
(show #t "(delete-queue! q1)    = " (delete-queue! q1)    "\n")
(show #t "insert " (insert-queue! q1 'c) "\n")
(show #t "(delete-queue! q1)    = " (delete-queue! q1)    "\n")



#+end_src

#+RESULTS:
: (insert-queue! q1 'a) = ((a) a)
: (insert-queue! q1 'b) = ((a b) b)
: (delete-queue! q1)    = ((b) b)
: insert ((b c) c)
: (delete-queue! q1)    = ((c) c)

I dare to say that this printed representation is correct, because it
not just displays the queue, but also shows what the end pointer marks.

Indeed, the queue is just a pair of a list and the final
pair. Moreover, even if the queue is empty, the last pair is not
destroyed, and therefore is displayed.

#+begin_src scheme :exports both :results output :noweb-ref print-queue
<<queue>>
(define (print-queue queue)
  (display (car queue)))
#+end_src

#+begin_src scheme :exports both :results output
<<queue>>
<<print-queue>>
(define q1 (make-queue))
(print-queue (insert-queue! q1 'a))
(newline)
(print-queue (insert-queue! q1 'b))
(newline)
(print-queue (delete-queue! q1))
(newline)
(print-queue (delete-queue! q1))
#+end_src

#+RESULTS:
: (a)
: (a b)
: (b)
: ()

Everything is fine.

*** DONE Exercise 3.22 procedural queue
    CLOSED: [2019-12-03 Tue 22:13]
#+begin_src scheme :exports both :results output :noweb-ref procedural-queue
    (define (make-queue)
      (let ((front-ptr (list))
	    (rear-ptr #f))
	(define (front)
	  (if (null? front-ptr)
	      (error "FRONT called with an empty queue" queue)
	      (car front-ptr)))
	(define (insert! x)
	  (let ((new-pair (cons x (list)))) 
	    (cond ((null? front-ptr) 
		   (set! front-ptr new-pair)
		   (set! rear-ptr  new-pair))
		  (else
		   (set-cdr! rear-ptr new-pair)
		   (set! rear-ptr new-pair)))))
	(define (delete!)
	  (if (not (null? front-ptr))
	      (set! front-ptr (cdr front-ptr))
	      (error "Queue already empty" front-ptr)))
	(define (dispatch m)
	  (cond ((eq? m 'empty-queue) (null? front-ptr))
		((eq? m 'front) (front))
		((eq? m 'insert!) insert!)
		((eq? m 'delete!) delete!)
                ((eq? m 'print) (display front-ptr))
		(else
		 (error "Undefined operation: queue" m)))  )
	dispatch))
  (define (front-queue z) 
    (z 'front))
  (define (empty-queue? z)
    (z 'empty-queue))
  (define (insert-queue! q z)
    ((q 'insert!) z)
    q)
  (define (delete-queue! q)
    ((q 'delete!))
    q)
  (define (print-queue q)
    (q 'print)
    (newline))

  (define q1 (make-queue))
  (empty-queue? q1)
  (insert-queue! q1 'a)
  (print-queue q1)
  (insert-queue! q1 'b)
  (print-queue q1)
  (delete-queue! q1)
  (print-queue q1)
  (delete-queue! q1)
  (print-queue q1)
#+end_src

#+RESULTS:
: (a)
: (a b)
: (b)
: ()

Well, makes sense. Not a very hard exercise.

*** DONE Exercise 3.23 dequeue
    CLOSED: [2019-12-03 Tue 23:24]

#+begin_src scheme :exports both :results result :noweb-ref dequeue
  (define (front-ptr deque) (car deque))
  (define (rear-ptr deque)
    (cdr deque))
  (define (set-front-ptr! deque item)
    (set-car! deque item))
  (define (set-rear-ptr! deque item)
    (set-cdr! deque item))
  (define (empty-deque? deque)
    (null? (front-ptr deque)))
  (define (make-deque) (cons '() '()))
  (define (get-item list-elem)
    (cdr list-elem))
  (define (get-backlink list-elem)
    (car list-elem))
  (define (front-deque deque)
    (if (empty-deque? deque)
	(error "FRONT called with an empty deque" deque)
	(get-item (car (front-ptr deque)))))
  (define (rear-deque deque)
    (if (empty-deque? deque)
	(error "REAR called with an empty deque" deque)
	(get-item (car (rear-ptr deque)))))
  (define (rear-insert-deque! deque item)
    (let ((new-pair (cons (cons #f item) '())))
      (cond ((empty-deque? deque)
	     (set-front-ptr! deque new-pair)
	     (set-rear-ptr! deque new-pair)
	     deque)
	    (else
	     (set-cdr! (rear-ptr deque) new-pair)
             (set-car! new-pair (rear-ptr deque))
	     (set-rear-ptr! deque new-pair)
	     deque))))
  (define (front-delete-deque! deque)
    (cond ((empty-deque? deque)
	   (error "FRONT-DELETE! called with an empty deque" deque))
	  (else (set-front-ptr! deque (cdr (front-ptr deque)))
                (set-car! (car (front-ptr deque)) '())
		deque)))
  (define (front-insert-deque! deque item)
    (let ((new-pair (cons (cons '() item) '())))
      (cond ((empty-deque? deque)
	     (set-front-ptr! deque new-pair)
	     (set-rear-ptr! deque new-pair)
	     deque)
	    (else
	     (set-cdr! new-pair (front-ptr deque))
             (set-car! (car (front-ptr deque)) new-pair)
             (set-front-ptr! deque new-pair)
            deque))))
  (define (rear-delete-deque! deque)
    (cond ((empty-deque? deque)
	   (error "REAR-DELETE! called with an empty deque" deque))
	  (else (set-rear-ptr! deque (caar (rear-ptr deque)))
                (if (not (null? (rear-ptr deque)))
                    (set-cdr! (rear-ptr deque) (list))
                    (set-front-ptr! deque '()))
		deque)))
(define (print-deque q)
  (display q))


(define dq1 (make-deque))
(front-insert-deque! dq1 'a)
(rear-insert-deque!  dq1 'b)
(front-delete-deque! dq1)
(rear-delete-deque!  dq1)
(empty-deque? dq1)
#+end_src

#+RESULTS:
: #t

*** Remark Table operations
Actually, these table operations are first required in the chapter 2,
Exercise-2.73. In order to avoid look-aheads, I am introducing this
pseudo-chapter so that the appropriate code could be tangled in.

#+begin_src scheme :exports both :results value :noweb-ref put-and-get
     (define (make-table)
       (let ((local-table (list '*table*)))
         (define (lookup key-1 key-2)
           (let ((subtable (assoc key-1 (cdr local-table))))
             (if subtable
                 (let ((record (assoc key-2 (cdr subtable))))
                   (if record
                       (cdr record)
                       false))
                 false)))
         (define (insert! key-1 key-2 value)
           (let ((subtable (assoc key-1 (cdr local-table))))
             (if subtable
                 (let ((record (assoc key-2 (cdr subtable))))
                   (if record
                       (set-cdr! record value)
                       (set-cdr! subtable
                                 (cons (cons key-2 value)
                                       (cdr subtable)))))
                 (set-cdr! local-table
                           (cons (list key-1
                                       (cons key-2 value))
                                 (cdr local-table)))))
           'ok)
         (define (dispatch m)
           (cond ((eq? m 'lookup-proc) lookup)
                 ((eq? m 'insert-proc!) insert!)
                 (else (error "Unknown operation -- TABLE" m))))
         dispatch))

     (define operation-table (make-table))
     (define get (operation-table 'lookup-proc))
     (define put (operation-table 'insert-proc!))
     (define coercion-table (make-table))
     (define get-coercion (coercion-table 'lookup-proc))
     (define put-coercion (coercion-table 'insert-proc!))
     
#+end_src

#+RESULTS:
: ok

*** DONE Exercise 3.24 tolerant tables
    CLOSED: [2019-12-04 Wed 18:07]

#+begin_src scheme :exports both :results output
  (define false #f)
  (define (make-table . o)
    (let ((same-key? (if (null? o) equal? (car o))))
      (let ((local-table (list '*table*)))
	(define (lookup key-1 key-2)
	  (let ((subtable
		 (assoc key-1 (cdr local-table) same-key?)))
	    (if subtable
		(let ((record
		       (assoc key-2 (cdr subtable) same-key?)))
		  (if record (cdr record) false))
		false)))
	(define (insert! key-1 key-2 value)
	  (let ((subtable
		 (assoc key-1 (cdr local-table) same-key?)))
	    (if subtable
		(let ((record
		       (assoc key-2 (cdr subtable) same-key?)))
		  (if record
		      (set-cdr! record value)
		      (set-cdr! subtable
				(cons (cons key-2 value)
				      (cdr subtable)))))
		(set-cdr! local-table
			  (cons (list key-1 (cons key-2 value))
				(cdr local-table)))))
	  'ok)
	(define (dispatch m)
	  (cond ((eq? m 'lookup-proc) lookup)
		((eq? m 'insert-proc!) insert!)
		(else (error "Unknown operation: TABLE" m))))
	dispatch)))
  (define (parity-checker a b)
    (if (= (remainder a 2) (remainder b 2))
        #t
        #f)) #;("not a very useful table")
  (define operation-table (make-table parity-checker))
  (define get (operation-table 'lookup-proc))
  (define put (operation-table 'insert-proc!))
  (put 1 2 (lambda () (display "test1") (newline)))
  ((get 3 4))
#+end_src

#+RESULTS:
: test1

This exercise would have been much-much harder with schemes lower than
version 7, as the ~assoc~ procedure doesn't take a comparator procedure.

*** DONE Exercise 3.25 multilevel tables
    CLOSED: [2019-12-06 Fri 20:35]

This exercise illustrates that it is never pays off to save on data
structures. The two-level structure is not flexible, so we are just using
nested tables.

#+begin_src scheme :exports both :results output
(display "Starting\n")
	 (define (make-table)
           (let ((local-table (list)))
	     (define (lookup key-list)
	       (let ((subtable (assoc (car key-list) local-table)))
		 (if subtable
		     (if (null? (cdr key-list))
                         (cdr subtable)
                         (((cdr subtable) 'lookup-proc) (cdr key-list)))
		     #f)))
	     (define (insert! key-list value)
	       (let* ((key (car key-list))
                      (subtable (assoc key local-table)))
                  (if subtable
                     (if (null? (cdr key-list))
                         (set-cdr! subtable value)
                         (if (procedure? (cdr subtable))
                             (((cdr subtable) 'insert-proc!) (cdr key-list) value)
                             (let ((subsubtable (make-table)))
                                  ((subsubtable 'insert-proc!) (cdr key-list) value)
                                  (set-cdr! subtable subsubtable))))
                     (set! local-table 
                           (cons 
                              (cons key 
                                 (if (null? (cdr key-list))
                                    value
                                    (let ((subsubtable (make-table)))
                                       ((subsubtable 'insert-proc!) 
                                        (cdr key-list) value) subsubtable))) 
                              local-table)))))
	     (define (dispatch m)
	       (cond ((eq? m 'lookup-proc) lookup)
		     ((eq? m 'insert-proc!) insert!)
                     (else (error "Unknown operation -- TABLE" m))))
	     dispatch))

	 (define operation-table (make-table))
	 (define get (operation-table 'lookup-proc))
	 (define put (operation-table 'insert-proc!))

  (display (put (list 'key1 'key2 'key3) 'test-value))
  (newline)
  (display (get (list 'key1 'key2 'key3)))
#+end_src

#+RESULTS:
: Starting
: #<undef>
: test-value

*** DONE Exercise 3.26 binary tree table
    CLOSED: [2019-12-06 Fri 20:53]

It is easy to implement a table lookup system based on an ordered set of
keys. A binary search tree is an easy example. In such a tree, every node
represents a key (with some payload value). The left child always has its key
ordered less than the right one, in every node. Searching is thus easy, you
start from the top of the tree, and follow right or left, depending whether
the key you are searching for is greater or less than the one you are looking
for. 

This should clearly require \(O(\log n)\) steps if the tree is well
balanced. Insertion, if implemented naively, may work according to the same
scheme. However, if we try to insert a long list of successive numbers, we
will get a very deep and very thin tree, which will reduce the problem to the
implementation based on lists.


The problem happens if the tree is _not_ well balanced. Several re-balancing
algorithms exist, that for example AVL-trees and RB-trees. Those are usually
applied on ~insert!~, when the tree's "badness" metric exceeds some value.

*** DONE Exercise 3.27 memoization
    CLOSED: [2019-12-07 Sat 16:08]

It is very straightforward why plain ~(memoize fib)~ would not work. Because
every call to the same function should be snapped with a call to the
memoizer. That is the memoization only rememebers a call with which it is
associated. Since ~fib~ calls ~fib~ again, not ~memo-fib~, only the final
result would be remembered.

We want to make a diagram for ~(memo-fib 3)~.

#+name: exercise-3-27
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-27.png
\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
       font=\sffamily,pics/two dots/.style={code={
       \node [draw,minimum size=5mm,circle,colored tokens={black!50}] 
       (#1-left) {};
      \node [draw,minimum size=5mm,circle,colored tokens={black!50},
      right=0pt of #1-left]
	  (#1-right) {};
      \node [rectangle, fit=(#1-left) (#1-right)] (#1){};
      }},
      every pin edge/.style={<-,very thick},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      node distance=4mm]

    \node (memoize-global)  {memoize: <...>};
    \node (fake1) [right=100mm of fib-global] {};  
    \node (memo-fib-global) [below=4mm of memoize-global.west,anchor=west] {memo-fib:};

    \node (g env) [box, fit=(memoize-global) (fake1) (memo-fib-global),
    pin={[text width=1cm,pin distance=10mm]left:global env}]
    { };
    \path
     node[below=2cm of memo-fib-global.west, anchor=west,align=left] (var-f) {f: lambda (n) <...>\\ 
      (fib implementation,\\ uses memo-fib)} 
     node[box,draw, minimum size=1cm, fit=(var-f),pin=left:E1] (E1-env) {}
     ($ (E1-env.north west)!0.9!(E1-env.north east) $) coordinate (aux3);
     \draw[->] (aux3) -- (aux3 |- g env.south);

     \node[below=2cm of var-f.west, anchor=west] (table-var) {table: \#<procedure dispatch>}
     node[right=7cm of table-var] (fake2) {};
     \node[box,draw, fit=(table-var) (fake2),pin=left:E2] (E2-env) {};
     \path ($ (E2-env.north west)!0.1!(E2-env.north east) $) coordinate (aux2);
     \draw[->] (aux2) -- (aux2 |- E1-env.south);
     \path coordinate[below=1.5cm of table-var.west] (aux)
     (aux)  pic{two dots=memo-fib}; 
     \draw[->] (memo-fib-right.center) to (E2-env.south -| memo-fib-right.center);
     \node[below=10mm of memo-fib-left,align=left,anchor=north] 
     {parameters: x\\
     body: <table lookup,\\ or uses f>} 
     edge[<-] (memo-fib-left.center);
     \draw[<-,to path={-- ++(-2cm,0) |- ($ (\tikztotarget) - (0,1cm) $)} 
                       -- (\tikztotarget)] 
     (memo-fib.west) to (memo-fib-global.east);
     \path ($ (E2-env.south west)!0.2!(E2-env.south east) $) node(fake) {}
      node [box,below=1cm of fake] (fake2) {n: 3} edge[->] (fake)
      node [below=5mm of fake2] {<memo-fib...>};
     \path ($ (E2-env.south west)!0.4!(E2-env.south east) $) node(fake) {}
      node [box,below=1cm of fake] (fake2) {n: 2} edge[->] (fake)
      node [below=5mm of fake2] {<memo-fib...>};
     \path ($ (E2-env.south west)!0.6!(E2-env.south east) $) node(fake) {}
      node [box,below=1cm of fake] (fake2) {n: 1} edge[->] (fake)
      node [below=5mm of fake2] {<memo-fib...>};

\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-27
[[file:exercise-3-27.png]]

I am not sure this is very explanatory, but seems to do the job...


*** Circuit simulation code

I am separating the circuit simulation code into a separate section, because
it is all very messy and scattered, and would be interfering with just
solving exercises.

#+begin_src scheme :exports both :results value :noweb-ref circuit-simulator-1
(define delay #f)
  (define (get-signal wire) (wire 'get-signal))
  (define (set-signal! wire new-value)
    ((wire 'set-signal!) new-value))
  (define (add-action! wire action-procedure)
    ((wire 'add-action!) action-procedure))

  (define (call-each procedures)
    (if (null? procedures)
	'done
	(begin ((car procedures))
	       (call-each (cdr procedures)))))

  (define (make-wire)
    (let ((signal-value 0) (action-procedures '()))
      (define (set-my-signal! new-value)
	(if (not (= signal-value new-value))
	    (begin (set! signal-value new-value)
		   (call-each action-procedures))
	    'done))
      (define (accept-action-procedure! proc)
	(set! action-procedures
	  (cons proc action-procedures))
	(proc))
      (define (dispatch m)
	(cond ((eq? m 'get-signal) signal-value)
	      ((eq? m 'set-signal!) set-my-signal!)
	      ((eq? m 'add-action!) accept-action-procedure!)
	      (else (error "Unknown operation: WIRE" m))))
      dispatch))

  (define a (make-wire))
  (define b (make-wire))
  (define c (make-wire))
  (define d (make-wire))
  (define e (make-wire))
  (define s (make-wire))

  (define (half-adder a b s c)
    (let ((d (make-wire)) (e (make-wire)))
      (or-gate a b d)
      (and-gate a b c)
      (inverter c e)
      (and-gate d e s)
      'ok))

  (define (full-adder a b c-in sum c-out)
    (let ((s (make-wire)) (c1 (make-wire)) (c2 (make-wire)))
      (half-adder b c-in s c1)
      (half-adder a s sum c2)
      (or-gate c1 c2 c-out)
      'ok))

  (define (inverter input output)
    (define (invert-input)
      (let ((new-value (logical-not (get-signal input))))
        #;(show #t "Inverter-delay=" inverter-delay "\n")        
	(after-delay inverter-delay
		     (lambda () (set-signal! output new-value)))))
    (add-action! input invert-input) 'ok)
  (define (logical-not s)
    (cond ((= s 0) 1)
	  ((= s 1) 0)
	  (else (error "Invalid signal" s))))  

  (define (after-delay delayd action)
    (add-to-agenda! (+ delayd (current-time the-agenda))
		    action
		    the-agenda))

  (define (propagate)
    #;(show #t "propagate: agenda=" (displayed the-agenda) "\n")
    (if (empty-agenda? the-agenda)
	'done
	(let ((first-item (first-agenda-item the-agenda)))
	  (first-item)
	  (remove-first-agenda-item! the-agenda)
	  (propagate))))

  (define (probe name wire)
    (add-action! wire
		 (lambda ()
		   (newline)
		   (display name) (display " ")
                   (display "time= ")
		   (display (current-time the-agenda))
		   (display "  New-value = ")
		   (display (get-signal wire)))))

  <<queue>>

  (define (make-time-segment time queue)
    (cons time queue))
  (define (segment-time s) (car s))
  (define (segment-queue s) (cdr s))

  (define (make-agenda) (list 0))
  (define (current-time agenda) (car agenda))
  (define (set-current-time! agenda time)
    (set-car! agenda time))
  (define (segments agenda) (cdr agenda))
  (define (set-segments! agenda segments)
    (set-cdr! agenda segments))
  (define (first-segment agenda) (car (segments agenda)))
  (define (rest-segments agenda) (cdr (segments agenda)))

  (define (empty-agenda? agenda)
    (null? (segments agenda)))

  (define (add-to-agenda! time action agenda)
    (define (belongs-before? segments)
      (or (null? segments)
	 (< time (segment-time (car segments)))))
    (define (make-new-time-segment time action)
      (let ((q (make-queue)))
	(insert-queue! q action)
	(make-time-segment time q)))
    (define (add-to-segments! segments)
      (if (= (segment-time (car segments)) time)
	  (insert-queue! (segment-queue (car segments))
			 action)
	  (let ((rest (cdr segments)))
	    (if (belongs-before? rest)
		(set-cdr!
		 segments
		 (cons (make-new-time-segment time action)
		       (cdr segments)))
		(add-to-segments! rest)))))
    (let ((segments (segments agenda)))
      (if (belongs-before? segments)
	  (set-segments!
	   agenda
	   (cons (make-new-time-segment time action)
		 segments))
	  (add-to-segments! segments))))

  (define (remove-first-agenda-item! agenda)
    (let ((q (segment-queue (first-segment agenda))))
      (delete-queue! q)
      (if (empty-queue? q)
	  (set-segments! agenda (rest-segments agenda)))))

  (define (first-agenda-item agenda)
    (if (empty-agenda? agenda)
	(error "Agenda is empty: FIRST-AGENDA-ITEM")
	(let ((first-seg (first-segment agenda)))
          #;(show #t "f-a-i:current-time=" (car agenda) "\n")
	  (set-current-time! agenda
			     (segment-time first-seg))
	  (front-queue (segment-queue first-seg)))))

  (define (logical-and s1 s2)
    (cond ((and (= 1 s1) (= s2 1)) 1)
	  (else 0)))
  (define (and-gate a1 a2 output)
    (define (and-action-procedure)
      (let ((new-value
	     (logical-and (get-signal a1) (get-signal a2))))
        #;(show #t "And-gate-delay=" and-gate-delay "\n")
	(after-delay
	 and-gate-delay
	 (lambda () (set-signal! output new-value)))))
    (add-action! a1 and-action-procedure)
    (add-action! a2 and-action-procedure)
    'ok)

  <<or-gate-primitive>>

  #;(display "Done defining the circuit simulator.\n")
  'done-defining-circuit-simulator
#+end_src

#+RESULTS:
: done-defining-circuit-simulator

For example, the procedure ~logical-and~ is not implemented
anywhere, so we will need to write it ourselves.

#+begin_src scheme :exports both :results output 
    <<circuit-simulator-1>>
    (define the-agenda (make-agenda))
    (define inverter-delay 2)
    (define and-gate-delay 3)
    (define or-gate-delay 5)

    (define input-1 (make-wire))
    (define input-2 (make-wire))
    (define sum (make-wire))
    (define carry (make-wire))
    (show #t "(probe 'sum sum):\n")
    (probe 'sum sum)
    (show #t "\n(probe 'carry carry):\n")
    (probe 'carry carry)
    (show #t "\n(half-adder input-1 input-2 sum carry):\n")
    (half-adder input-1 input-2 sum carry)
    (show #t "\n(set-signal! input-1 1):\n")
    (set-signal! input-1 1)
    (show #t "\n(propagate):\n")
    (propagate)
    (show #t "\n(set-signal! input-2 1):\n")
    (set-signal! input-2 1)    
    (show #t "\n(propagate):\n")
    (propagate)
#+end_src

#+RESULTS:
#+begin_example
(probe 'sum sum):

(probe 'carry carry):

(half-adder input-1 input-2 sum carry):

(set-signal! input-1 1):

(propagate):

(set-signal! input-2 1):

(propagate):

carry time= 11  New-value = 1
#+end_example



*** DONE Exercise 3.28 primitive or-gate
    CLOSED: [2019-12-08 Sun 23:43]

In this exercise, there is one caveat that makes life of programmers
miserable. That is, 0 does not represent a false value in scheme. So
writing a readable code was a bit difficult, and the code below is
probably not correct.

#+begin_src scheme :exports both :results output :noweb-ref or-gate-primitive
(define (logical-or s1 s2)
    (cond ((or (= s1 1) (= s2 1)) 1)
	  (else 0)))
(define (or-gate a1 a2 output)
    (define (or-action-procedure)
      (let ((new-value
	     (logical-or (get-signal a1) (get-signal a2))))
        #;(show #t "or-gate-delay=" or-gate-delay "\n")
	(after-delay
	 or-gate-delay
	 (lambda () (set-signal! output new-value)))))
    (add-action! a1 or-action-procedure)
    (add-action! a2 or-action-procedure)
    'ok)
#+end_src

This code is used in the previous section. [[Circuit simulation code
]]

*** DONE Exercise 3.29 Compound or-gate
    CLOSED: [2019-12-08 Sun 23:45]

\( \vee (a,b) = \wedge(\neg a, \neg b)\)

#+begin_src scheme :exports both :results output :noweb-ref or-gate-procedural
(define (or-gate a b c)
    (let ((d (make-wire)) (e (make-wire)))
      (inverter a d)
      (inverter b e)
      (and-gate d e c)
      'ok))
#+end_src

I have no idea how slow this works, and we don't have a simulation routine
to check. But the delay should be the sum of the and-gate delay and just one
of the inverter delays (because the two inverters work in parallel).

*** DONE Exercise 3.30 ripple-carry adder
    CLOSED: [2019-12-08 Sun 23:58]

#+begin_src scheme :exports both :results output
<<circuit-simulator-1>>
<<or-gate-primitive>>

    (define the-agenda (make-agenda))
    (define inverter-delay 2)
    (define and-gate-delay 3)
    (define or-gate-delay 5)

  (define (make-wire-list n my-list)
    (if (= n 0)
	my-list
	(make-wire-list (- n 1) (cons (make-wire) my-list))))
  (define test-length 2)
  (define A (make-wire-list test-length '()))
  (define B (make-wire-list test-length '()))
  (define S (make-wire-list test-length '()))
  (define C (make-wire))

  (define (ripple-carry-adder a b s c)
    (let ((A_n (car a))
	  (B_n (car b))
	  (S_n (car s))
	  (C_n-1 (make-wire)))
      (full-adder A_n B_n c S_n C_n-1)
      (if (null? (cdr a))
	  C_n-1
	  (ripple-carry-adder (cdr a) (cdr b) (cdr s) C_n-1))))
  (define C_out (ripple-carry-adder A B S C))

  (probe 'C_out C_out)
  (set-signal! (list-ref A 1) 1)
  (set-signal! (list-ref A 0) 1)
  (set-signal! (list-ref B 1) 1)
  (propagate)
#+end_src

#+RESULTS:
: 
: C_out time= 0  New-value = 0
: C_out time= 16  New-value = 1

This ripple-carry-adder is not very efficient. Also, bits are represented in
the little-ending format. Also, we can still not test it, since the
simulation function is not given.

*** DONE Exercise 3.31 Initial propagation 
    CLOSED: [2019-12-09 Mon 00:16]

Initial propagation is needed for in initial intermediate values of
the wires to be consistent.

In particular, look at the inverter gate. If we don't run
initialisation, then at time 0, the gate would have it's input as 0
(which is a normal state for a newly-created wire), and it's output as
0 too. But this condition for an inverter is wrong.

*** DONE Exercise 3.32 Order matters
    CLOSED: [2019-12-09 Mon 00:26]

The problem with adding operations in a standard list is that the
intermediate results are getting in the execution after the final
ones.

In this particular example, changing (0,1) to (1,0), we have to go
through (1,1). And it doesn't matter than we are going to (1,0) after,
because the simulation for (1,1) will be in the queue later. 

*** Constraint propagation system

In this section I will place common code for the constraint
propagation system, because it is quite big.

#+begin_src scheme :exports both :results value :noweb-ref constraints-system
  (define false #f)
  (define true #t)
  (define (adder a1 a2 sum)
    (define (process-new-value)
      (cond ((and (has-value? a1) (has-value? a2))
	     (set-value! sum
			 (+ (get-value a1) (get-value a2))
			 me))
	    ((and (has-value? a1) (has-value? sum))
	     (set-value! a2
			 (- (get-value sum) (get-value a1))
			 me))
	    ((and (has-value? a2) (has-value? sum))
	     (set-value! a1
			 (- (get-value sum) (get-value a2))
			 me))))
    (define (process-forget-value)
      (forget-value! sum me)
      (forget-value! a1 me)
      (forget-value! a2 me)
      (process-new-value))
    (define (me request)
      (cond ((eq? request 'I-have-a-value)
	     (process-new-value))
	    ((eq? request 'I-lost-my-value) (process-forget-value))
	    (else (error "Unknown request: ADDER" request))))
    (connect a1 me)
    (connect a2 me)
    (connect sum me)
    me)

  (define (inform-about-value constraint)
    (constraint 'I-have-a-value))
  (define (inform-about-no-value constraint)
    (constraint 'I-lost-my-value))

  (define (multiplier m1 m2 product)
    (define (process-new-value)
      (cond ((or (and (has-value? m1) (= (get-value m1) 0))
		 (and (has-value? m2) (= (get-value m2) 0)))
	     (set-value! product 0 me))
	    ((and (has-value? m1) (has-value? m2))
	     (set-value! product
			 (* (get-value m1) (get-value m2))
			 me))
	    ((and (has-value? product) (has-value? m1))
	     (set-value! m2
			 (/ (get-value product)
			    (get-value m1))
			 me))
	    ((and (has-value? product) (has-value? m2))
	     (set-value! m1
			 (/ (get-value product)
			    (get-value m2))
			 me))))
    (define (process-forget-value)
      (forget-value! product me)
      (forget-value! m1 me)
      (forget-value! m2 me)
      (process-new-value))
    (define (me request)
      (cond ((eq? request 'I-have-a-value)
	     (process-new-value))
	    ((eq? request 'I-lost-my-value) (process-forget-value))
	    (else (error "Unknown request: MULTIPLIER"
			 request))))
    (connect m1 me)
    (connect m2 me)
    (connect product me)
    me)

  (define (constant value connector)
    (define (me request)
      (error "Unknown request: CONSTANT" request))
    (connect connector me)
    (set-value! connector value me)
    me)

  (define (probe name connector)
    (define (print-probe value)
      (newline) (display "Probe: ") (display name)
      (display " = ") (display value))
    (define (process-new-value)
      (print-probe (get-value connector)))
    (define (process-forget-value) (print-probe "?"))
    (define (me request)
      (cond ((eq? request 'I-have-a-value)
	     (process-new-value))
	    ((eq? request 'I-lost-my-value) (process-forget-value))
	    (else (error "Unknown request: PROBE" request))))
    (connect connector me)
    me)

  (define (make-connector)
    (let ((value false) (informant false) (constraints '()))
      (define (set-my-value newval setter)
	(cond ((not (has-value? me))
	       (set! value newval)
	       (set! informant setter)
	       (for-each-except setter
				inform-about-value
				constraints))
	      ((not (= value newval))
	       (error "Contradiction" (list value newval)))
	      (else 'ignored)))
      (define (forget-my-value retractor)
	(if (eq? retractor informant)
	    (begin (set! informant false)
		   (for-each-except retractor
				    inform-about-no-value
				    constraints))
	    'ignored))
      (define (connect new-constraint)
	(if (not (memq new-constraint constraints))
	    (set! constraints
	      (cons new-constraint constraints)))
	(if (has-value? me)
	    (inform-about-value new-constraint))
	'done)
      (define (me request)
	(cond ((eq? request 'has-value?)
	       (if informant true false))
	      ((eq? request 'value) value)
	      ((eq? request 'set-value!) set-my-value)
	      ((eq? request 'forget) forget-my-value)
	      ((eq? request 'connect) connect)
	      (else (error "Unknown operation: CONNECTOR"
			   request))))
      me))

  (define (for-each-except exception procedure list)
    (define (loop items)
      (cond ((null? items) 'done)
	    ((eq? (car items) exception) (loop (cdr items)))
	    (else (procedure (car items))
			 (loop (cdr items)))))
    (loop list))

  (define (has-value? connector)
    (connector 'has-value?))
  (define (get-value connector)
    (connector 'value))
  (define (set-value! connector new-value informant)
    ((connector 'set-value!) new-value informant))
  (define (forget-value! connector retractor)
    ((connector 'forget) retractor))
  (define (connect connector new-constraint)
    ((connector 'connect) new-constraint))

#+end_src

#+RESULTS:
: #<undef>

#+begin_src scheme :exports both :results output
  <<constraints-system>>
  (define (celsius-fahrenheit-converter c f)
    (let ((u (make-connector))
	  (v (make-connector))
	  (w (make-connector))
	  (x (make-connector))
	  (y (make-connector)))
      (multiplier c w u)
      (multiplier v x u)
      (adder v y f)
      (constant 9 w)
      (constant 5 x)
      (constant 32 y)
      'ok))

  (define C (make-connector))
  (define F (make-connector))

  (celsius-fahrenheit-converter C F)
  (probe "Celsius temp" C)
  (probe "Fahrenheit temp" F)

  (set-value! C 25 'user)
  #;(set-value! F 212 'user) #;("errors")
  (forget-value! C 'user)
  (set-value! F 212 'user)

#+end_src

#+RESULTS:
: 
: Probe: Celsius temp = 25
: Probe: Fahrenheit temp = 77
: Probe: Celsius temp = ?
: Probe: Fahrenheit temp = ?
: Probe: Fahrenheit temp = 212
: Probe: Celsius temp = 100

*** DONE Exercise 3.33 averager constraint
    CLOSED: [2019-12-18 Wed 11:29]

#+begin_src scheme :exports both :results output :noweb-ref constraints-averager
(define (averager a b c)
    (define (process-new-value)
      (cond 
	    ((and (has-value? a) (has-value? b))
	     (set-value! c
			 (/ (+ (get-value a) (get-value b)) 2)
			 me))
	    ((and (has-value? c) (has-value? a))
	     (set-value! b
			 (- (* 2 (get-value product))
			    (get-value a))
			 me))
	    ((and (has-value? c) (has-value? b))
	     (set-value! a
			 (- (* 2 (get-value c))
			    (get-value b))
			 me))))
    (define (process-forget-value)
      (forget-value! c me)
      (forget-value! a me)
      (forget-value! b me)
      (process-new-value))
    (define (me request)
      (cond ((eq? request 'I-have-a-value)
	     (process-new-value))
	    ((eq? request 'I-lost-my-value) (process-forget-value))
	    (else (error "Unknown request: AVERAGER"
			 request))))
    (connect a me)
    (connect b me)
    (connect c me)
    me)

#+end_src

#+begin_src scheme :exports both :results output
<<constraints-system>>
<<constraints-averager>>

(define localA (make-connector))
(define localB (make-connector))
(define localC (make-connector))
(averager localA localB localC)

(probe "localA: " localA)
(probe "localB: " localB)
(probe "localC: " localC)
(set-value! localA 25 'user)
(set-value! localB 27 'user)
(guard (err 
         (else (show #t "\nExpected failure: " (displayed err) "\n")))
  (set-value! localC 22 'user))
(forget-value! localA 'user)
(set-value! localC 22 'user)
#+end_src

#+RESULTS:
#+begin_example

Probe: localA:  = 25
Probe: localB:  = 27
Probe: localC:  = 26
Expected failure: {Exception #19 user "Contradiction" ((26 22)) #f #f}

Probe: localA:  = ?
Probe: localC:  = ?
Probe: localC:  = 22
Probe: localA:  = 17
#+end_example

*** DONE Exercise 3.34 Wrong squarer
    CLOSED: [2019-12-18 Wed 12:30]

The problem with this system is that the inversion procedure wouldn't
work. That is, the multiplier has three connections, and every two
define the third one. This is not the case with the squarer, as in the
formula \( a \cdot a = b \), if we are given \(b\), we immediately get
the value on both of the connectors leading to \(a\).

*** DONE Exercise 3.35 Correct squarer
    CLOSED: [2019-12-18 Wed 12:47]

#+begin_src scheme :exports both :results output :noweb-ref constraints-squarer
          (define (squarer a b)
            (define (process-new-value)
              (if (has-value? b)
                  (if (< (get-value b) 0)
                      (error "square less than 0 -- SQUARER" (get-value b))
                      (set-value! a 
                                  (sqrt (get-value b))
                                  me))
                  (if (has-value? a)
                      (set-value! b
                                  (* (get-value a) (get-value a))
                                  me))))
            (define (process-forget-value) 
               (forget-value! b me)
               (forget-value! a me))
            (define (me request) 
                (cond ((eq? request 'I-have-a-value)
	                 (process-new-value))
	              ((eq? request 'I-lost-my-value) 
                         (process-forget-value))
	    (else (error "Unknown request: SQUARER" request))))
            (connect a me)
            (connect b me)
            me)
#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
<<constraints-squarer>>
<<constraints-system>>

(define localA (make-connector))
(define localB (make-connector))
(squarer localA localB)
(probe "localA: " localA)
(probe "localB: " localB)
(set-value! localA 25 'user)
(guard (err 
         (else (show #t "\nExpected failure: " (displayed err))))
  (set-value! localB 22 'user))
(forget-value! localA 'user)
(set-value! localB 22 'user)
#+end_src

#+RESULTS:
: 
: Probe: localA:  = 25
: Probe: localB:  = 625
: Expected failure: {Exception #19 user "Contradiction" ((625 22)) #f #f}
: Probe: localA:  = ?
: Probe: localB:  = ?
: Probe: localB:  = 22
: Probe: localA:  = 4.69041575982343

*** DONE Exercise 3.36 Connector environment diagram                   :tikz:
    CLOSED: [2019-12-21 Sat 20:27]

We are studying the following code:
#+begin_src scheme :exports both :results output
(define a (make-connector))
(define b (make-connector))
(set-value! a 10 'user)
#+end_src

#+name: exercise-3-36
#+header: :imagemagick yes :iminoptions -density 300 :imoutoptions -geometry 1000
#+header: :fit yes :headers '("\\usepackage{tikz} \\usetikzlibrary{positioning,fit,petri,arrows,calc,matrix,quotes}")
#+header: :buffer on
#+begin_src latex :results raw file :exports both :file exercise-3-36.png
\begin{tikzpicture}[inner sep=0mm,>=stealth',very thick,color=black!50,
       every node/.style={font=\sffamily,align=left},
       font=\sffamily,pics/two dots/.style={code={
       \node [draw,minimum size=5mm,circle,colored tokens={black!50}] 
       (#1-left) {};
      \node [draw,minimum size=5mm,circle,colored tokens={black!50},
      right=0pt of #1-left]
	  (#1-right) {};
      \node [rectangle, fit=(#1-left) (#1-right)] (#1){};
      }},
      every pin edge/.style={<-,very thick},
      box/.style={draw,rectangle,inner sep=#1},box/.default=2mm,
      envi/.style={matrix of nodes, align=left,
                  every node/.style={anchor=west}, 
                  inner sep={0.7mm},
                  execute at end cell={\vphantom{()}},
                  draw},
      node distance=4mm]

    \node (a-global)  {a:};
    \node (fake1) [right=150mm of a] {};  
    \node (b-global) [below=4mm of a-global.west,anchor=west] {b:};
    \node (iov-global) [below=4mm of b-global.west,anchor=west] {inform-about-value:};
    \node (sv-global) [below=4mm of iov-global.west,anchor=west] {set-value!:};

    \node (g-env) [box, fit=(a-global) (fake1) (b-global) (iov-global) (sv-global),
    pin={[text width=1cm,pin distance=10mm]left:global env}]
    { };
     \path ($ (g-env.south west)!0.3!(g-env.south east) $) coordinate (fake1)
      coordinate[below=1cm of fake1] (fake) (fake) pic{two dots=set-to-value}
      (set-to-value) edge[<-,to path={|- (\tikztotarget)}] (sv-global.east)
      (set-to-value-right.center) edge[->] (fake1 -| set-to-value-right.center);

     \path ($ (g-env.south west)!0.5!(g-env.south east) $) coordinate (fake1)
      coordinate[below=1cm of fake1] (fake) (fake) pic{two dots=i-a-v}
      (i-a-v) edge[<-,to path={|- (\tikztotarget)}] (iov-global.east)
      (i-a-v-right.center) edge[->] (fake1 -| i-a-v-right.center);


     \path ($ (g-env.south west)!0.1!(g-env.south east) $) node(fake) {};
     \matrix (a) [envi,
                  below=of fake]
     {
       value: 10\\
       informant: 'user\\
       constraints: '() \\
       |(a-set-my-value)| set-my-value: \\
       |(a-forget-my-value)| forget-my-value: \\
       |(a-connect)| connect: \\
       |(a-me)| me:\\
     } edge[->] (fake);

     \path coordinate[right=2.5cm of a-me] (aux)
      (aux) pic{two dots=amev}
      (amev) edge [<-] (a-me) (amev-right.center) 
             edge [->,to path={|- (\tikztotarget)}] ($ (a.east)$)
             node[below=0.5cm of amev-left] {parameters: newvalue\\
                                             \phantom{parameters: }setter\\ 
                                             body: ... }
             edge[<-] (amev-left.center);
     \draw[->] (a-global.east) to[to path={  -| (\tikztotarget)}] (amev);

     \path ($ (g-env.south west)!0.9!(g-env.south east) $) node(fake) {};
     \matrix (b) [ below=of fake,envi]
     {
       value: \#f\\
       informant: \#f\\
       constraints: '() \\
       |(b-set-my-value)| set-my-value: <...>\\
       |(b-forget-my-value)| forget-my-value: <...> \\
       |(b-connect)| connect: <...> \\
       |(b-me)| me:\\
     } edge[->] (fake);

     \path coordinate[right=40mm of b-me] (aux)
      (aux) pic{two dots=bmev}
      (bmev) edge [<-] (b-me) 
             (bmev-right.center)  
                edge [->,to path={|- (\tikztotarget)}]
                  ($ (b.east) + (0,0mm)$)
             node[below=0.5cm of bmev-left] {parameters: newvalue\\
                                             \phantom{parameters: }setter\\ 
                                             body: ... }
             edge[<-] (bmev-left.center);

     \draw[->] (b-global.east) to[to path={-| (\tikztotarget)}] (bmev);

     \matrix (smv) [below=2cm of a, envi]
     {
       newval: 10\\
       setter: 'user\\
     } edge[->] (a)
     ($ (a.south)!0.5!(smv.north) $) node[anchor=east]
      {(set-my-value 10 'user)};

     \matrix (fee) [below=2cm of smv,envi]
     {
      exception: 'user\\
      |(pp)| procedure:\\
      constraints: '()\\
      loop: <...> \\
     } edge[->] (smv)
      (pp.east) edge[->, to path={-| (\tikztotarget)}] (i-a-v)
     ($ (smv.south)!0.5!(fee.north)$) node[anchor=east]
     {(for-each-except\\
       'user \\
       inform-about-value \\
       '())};
     \matrix (loop) [below=1cm of fee, envi]
     {
       items: '()\\
     } edge[->] (fee)
     ($ (fee.south)!0.5!(loop.north) $) node[anchor=east]
     {(loop '())}
     node[below=of loop,anchor=north]
     {(cond\\
        ((null? items)\\
          'done)\\
        ((eq? (car items) exception)\\
        (loop (cdr items)))\\
        (else\\
        (procedure (car items))\\
        (loop (cdr items))))};
     
\end{tikzpicture}
#+end_src

#+RESULTS: exercise-3-36
[[file:exercise-3-36.png]]

Not as much of a difficult drawing exercise, still took me about 5
hours. Drawing is hard.

*** DONE Exercise 3.37 Expression-based constraints
    CLOSED: [2019-12-21 Sat 21:20]
#+begin_src scheme :exports both :results output :noweb-ref constraints-expressions
  (define (c+ x y)
    (let ((z (make-connector)))
      (adder x y z)
      z))
  (define (c* x y)
    (let ((z (make-connector)))
      (multiplier x y z)
      z))
  (define (cv value)
    (let ((z (make-connector)))
      (constant value z)
      z))
  (define (c/ x y)
    (let ((z (make-connector)))
      (multiplier y z x)
      z))  
#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
<<constraints-system>>
<<constraints-expressions>>
  (define (celsius-fahrenheit-converter x)
    (c+ 
     (c* 
      (c/ (cv 9) (cv 5))
      x)
     (cv 32)))
  (define C (make-connector))
  (define F (celsius-fahrenheit-converter C))
(probe "Celsius temp" C)
(probe "Fahrenheit temp" F)
(set-value! F 212 'user)

#+end_src

#+RESULTS:
: 
: Probe: Fahrenheit temp = 212
: Probe: Celsius temp = 100

This turned out to be a very easy task. The only trick here really is
to use the multiplies as a divider.

*** TODO Check that every exercise with pictures has tags



*** TODO Figure 3.29 Sequence diagram                              :plantuml:
*** TODO Figure 3.30                                                   :tikz:
*** DONE Exercise 3.38 Timing
    CLOSED: [2019-12-21 Sat 22:48]

The three users to the following:

Peter: (set! balance (+ balance 10))
Paul: (set! balance (- balance 20))
Mary: (set! balance (- balance (/ balance 2)))

**** a
The three possible code orderings are the following:

#+begin_src scheme :exports both :results value
(define balance 100)
(set! balance (+ balance 10))
(set! balance (- balance 20))
(set! balance (- balance (/ balance 2)))
balance
#+end_src

#+RESULTS:
: 45

#+begin_src scheme :exports both :results value
(define balance 100)
(set! balance (- balance 20))
(set! balance (- balance (/ balance 2)))
(set! balance (+ balance 10))
balance
#+end_src

#+RESULTS:
: 50

#+begin_src scheme :exports both :results value
(define balance 100)
(set! balance (- balance (/ balance 2)))
(set! balance (- balance 20))
(set! balance (+ balance 10))
balance
#+end_src

#+RESULTS:
: 40

**** b

#+begin_src plantuml :exports both :file exercise-3-38.png
@startuml
skinparam monochrome true
actor "   Peter   " as Peter
actor "   Paul   "  as Paul
actor "   Mary   "  as Mary 
entity "   Bank   " as Bank
rnote over Bank: $100
Mary -> Bank: Access\n balance
Bank -> Mary: $100
note over Mary: $100
Paul -> Bank: Access\n balance
Bank -> Paul: $100
note over Paul: $100
Peter -> Bank: Access\n balance
Bank -> Paul: $100
note over Mary: $100/2=$50
Mary -> Bank: set-balance! $50
rnote over Bank: $50
note over Paul: $100-$20=$80
Paul -> Bank: set-balance! $80
rnote over Bank: $80
note over Peter: $100+$10=$110
Peter -> Bank: set-balance! $110
rnote over Bank: $110
@enduml
#+end_src

#+RESULTS:
[[file:exercise-3-38.png]]

Obviously, the values of 50, 80 and 110 are wrong. Any of those can
end up as the final value, depending on the timing of ~set-balance!~.
*** Implementing ~(parallel-execute)~ and serializers

#+begin_src scheme :exports both :results output :noweb-ref parallel-execute
(define (parallel-execute . forms)
  (let ((myo (open-output-string)))
    (define (create-threads . forms)
    (if (null? forms)
	(list)
	(let ((ctxi (thread-start!
		     (make-thread
		      (lambda () (parameterize ((current-output-port myo))
				((car forms))))))))
	  (cons ctxi (apply create-threads (cdr forms))))))
  (define (wait-threads thread-list)
    (if (null? thread-list)
	#t
	(begin (thread-join! (car thread-list))
	       (wait-threads (cdr thread-list)))))
  (wait-threads (apply create-threads forms))
  (display (get-output-string myo))))

#+end_src

#+begin_src scheme :exports both :results output
<<parallel-execute>>
(parallel-execute 
  (lambda () (thread-sleep! 3) (display "hello1") (newline))
  (lambda () (display "hello2") (newline)))
(display "hello3\n")
#+end_src

#+RESULTS:
: hello2
: hello1
: hello3

#+begin_src scheme :exports both :results value
<<parallel-execute>>
(define x 10)
(parallel-execute
(lambda () (thread-sleep! 1) (set! x (* x x)))
(lambda () (set! x (+ x 1))))
x
#+end_src

#+RESULTS:
: 121

#+begin_src scheme :exports both :results output :noweb-ref make-serializer
  (define false #f)
  (define true #t)
  (define central-old-mutex (make-mutex 'global-srfi-18-mutex))
  (set! make-mutex #f)
  (define (test-and-set! cell)
    (mutex-lock! central-old-mutex)
    (let ((output (if (car cell) true (begin (set-car! cell true) false))))
      (mutex-unlock! central-old-mutex)
      output))

  (define (make-mutex)
    (let ((cell (list false)))
      (define (the-mutex m)
	(cond ((eq? m 'acquire)
	       (if (test-and-set! cell)
		   (the-mutex 'acquire)))
	      ((eq? m 'release) (clear! cell))))
      the-mutex))
  (define (clear! cell) (set-car! cell false))

  (define (make-serializer)
    (let ((mutex (make-mutex)))
      (lambda (p)
	(define (serialized-p . args)
	  (mutex 'acquire)
	  (let ((val (apply p args)))
	    (mutex 'release)
	    val))
	serialized-p)))

#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output :noweb-ref make-parallel-account
  (define (make-account balance)
    (define (withdraw amount)
      (if (>= balance amount)
	  (begin (set! balance (- balance amount))
		 balance)
	  "Insufficient funds"))
    (define (deposit amount)
      (set! balance (+ balance amount))
      balance)
    (let ((protected (make-serializer)))
      (define (dispatch m)
	(cond ((eq? m 'withdraw) (protected withdraw))
	      ((eq? m 'deposit) (protected deposit))
	      ((eq? m 'balance) balance)
	      (else (error "Unknown request: MAKE-ACCOUNT"
			   m))))
      dispatch))
#+end_src

*** DONE Exercise 3.39 Serializer
    CLOSED: [2019-12-23 Mon 05:11]

The original code is the following:

#+begin_src scheme :exports both :results output
(define x 10)
(parallel-execute
(lambda () (set! x (* x x)))
(lambda () (set! x (+ x 1))))
#+end_src

The original five outcomes were the following:

 - 101: P1 sets x to 100 and then P2 increments x to 101.
 - 121: P2 increments x to 11 and then P1 sets x to x * x .
 - 110: P2 changes x from 10 to 11 between the two times that
   P1 accesses the value of x during the evaluation of (* x x) .
 - 11:  P2 accesses x , then P1 sets x to 100, then P2 sets x .
 - 100: P1 accesses x (twice), then P2 sets x to 11, then P1 sets x .

We are serializing one of the branches:

#+begin_src scheme :exports both :results output
  (define x 10)
  (define s (make-serializer))
  (parallel-execute
   (lambda () (set! x ((s (lambda () (* x x))))))
   (s (lambda () (set! x (+ x 1)))))
#+end_src

In this case, the additive branch is fully serialized, and the
multiplicative had assignment and multiplication detached. The options
121 and 101 still remain, as they don't depend on the internal
serialization. The branch resulting in 110 is disabled, because the
read access to ~x~ is guaranteed to be sequential. The branch
resulting in 11 is also disabled, since accessing and setting is
guaranteed too happen together in the second branch. The branch
resulting in 100 remains a possible option, since the computation of
~(* x x)~ and the assignment are not guaranteed to happen in order.

So in the end, the three remaining options are:

 - 101: P1 sets x to 100 and then P2 increments x to 101.
 - 121: P2 increments x to 11 and then P1 sets x to x * x .
 - 100: P1 accesses x (twice), then P2 sets x to 11, then P1 sets x .

*** DONE Exercise 3.40 Three parallel multiplications
    CLOSED: [2019-12-29 Sun 04:32]
**** Part 1
#+begin_src scheme :exports both :results output
(define x 10)
(parallel-execute (lambda () (set! x (* x x)))
                  (lambda () (set! x (* x x x))))
#+end_src

Here there are two read operations and one write operation in the
first thread, and three read operations and one write operation in the
second branch. 

So we need to find the number of unique interleavings of two
sequences: (1 2 3 4) and (a b c). The total number of interleavings is
\(C_{x+y}^{x}\), which is 35, although it doesn't mean that all
interleavings produce different outcomes.

Those sequences can be generated algorithmically:
https://math.stackexchange.com/questions/628120/number-of-possible-interleavings-of-two-strings-of-lengths-m-and-n
https://stackoverflow.com/questions/36260956/all-possible-ways-to-interleave-two-strings

It should be also possible to write a scheme macro to serialize
~parallel-execute~. And it should also be possible to do it
efficiently.

However, at the moment it seems rather feasible to write out
all possible serializations (interleavings) by hand.

In total this makes the following sequences:

| #op | 1      | 2      | 3       | 4       | 5       | 6       | 7       | Result     |
|-----+--------+--------+---------+---------+---------+---------+---------+------------|
|   1 | 1 read | 1 read | 1 write | 2 read  | 2 read  | 2 read  | 2 write | 1 00 00 00 |
|   2 | 1 read | 1 read | 2 read  | 1 write | 2 read  | 2 read  | 2 write | 1 00 00 0  |
|   3 | 1 read | 1 read | 2 read  | 2 read  | 1 write | 2 read  | 2 write | 1 00 00    |
|   4 | 1 read | 1 read | 2 read  | 2 read  | 2 read  | 1 write | 2 write | 1 00 0     |
|   5 | 1 read | 1 read | 2 read  | 2 read  | 2 read  | 2 write | 1 write | 1 00       |
|   6 | 1 read | 2 read | 1 read  | 1 write | 2 read  | 2 read  | 2 write | 1 00 00 0  |
|   7 | 1 read | 2 read | 1 read  | 2 read  | 1 write | 2 read  | 2 write | 1 00 00    |
|   8 | 1 read | 2 read | 1 read  | 2 read  | 2 read  | 1 write | 2 write | 1 00 0     |
|   9 | 1 read | 2 read | 1 read  | 2 read  | 2 read  | 2 write | 1 write | 1 00       |
|  10 | 1 read | 2 read | 2 read  | 1 read  | 1 write | 2 read  | 2 write | 1 00 00    |
|  11 | 1 read | 2 read | 2 read  | 1 read  | 2 read  | 1 write | 2 write | 1 00 0     |
|  12 | 1 read | 2 read | 2 read  | 1 read  | 2 read  | 2 write | 1 write | 1 00       |
|  13 | 1 read | 2 read | 2 read  | 2 read  | 1 read  | 1 write | 2 write | 1 00 0     |
|  14 | 1 read | 2 read | 2 read  | 2 read  | 1 read  | 2 write | 1 write | 1 00       |
|  15 | 1 read | 2 read | 2 read  | 2 read  | 2 write | 1 read  | 1 write | 1 00 00    |
|  16 | 2 read | 1 read | 1 read  | 1 write | 2 read  | 2 read  | 2 write | 1 00 00 0  |
|  17 | 2 read | 1 read | 1 read  | 2 read  | 1 write | 2 read  | 2 write | 1 00 00    |
|  18 | 2 read | 1 read | 1 read  | 2 read  | 2 read  | 1 write | 2 write | 1 00 0     |
|  19 | 2 read | 1 read | 1 read  | 2 read  | 2 read  | 2 write | 1 write | 1 00       |
|  20 | 2 read | 1 read | 2 read  | 1 read  | 1 write | 2 read  | 2 write | 1 00 00    |
|  21 | 2 read | 1 read | 2 read  | 1 read  | 2 read  | 1 write | 2 write | 1 00 0     |
|  22 | 2 read | 1 read | 2 read  | 1 read  | 2 read  | 2 write | 1 write | 1 00       |
|  23 | 2 read | 1 read | 2 read  | 2 read  | 1 read  | 1 write | 2 write | 1 00 0     |
|  24 | 2 read | 1 read | 2 read  | 2 read  | 1 read  | 2 write | 1 write | 1 00       |
|  25 | 2 read | 1 read | 2 read  | 2 read  | 2 write | 1 read  | 1 write | 1 00 00    |
|  26 | 2 read | 2 read | 1 read  | 1 read  | 1 write | 2 read  | 2 write | 1 00 00    |
|  27 | 2 read | 2 read | 1 read  | 1 read  | 2 read  | 1 write | 2 write | 1 00 0     |
|  28 | 2 read | 2 read | 1 read  | 1 read  | 2 read  | 2 write | 1 write | 1 00       |
|  29 | 2 read | 2 read | 1 read  | 2 read  | 1 read  | 1 write | 2 write | 1 00 0     |
|  30 | 2 read | 2 read | 1 read  | 2 read  | 1 read  | 2 write | 1 write | 1 00       |
|  31 | 2 read | 2 read | 1 read  | 2 read  | 2 write | 1 read  | 1 write | 1 00 00    |
|  32 | 2 read | 2 read | 2 read  | 1 read  | 1 read  | 1 write | 2 write | 1 00 0     |
|  33 | 2 read | 2 read | 2 read  | 1 read  | 1 read  | 2 write | 1 write | 1 00       |
|  34 | 2 read | 2 read | 2 read  | 1 read  | 2 write | 1 read  | 1 write | 1 00 00    |
|  35 | 2 read | 2 read | 2 read  | 2 write | 1 read  | 1 read  | 1 write | 1 00 00 00 |

So the total set of ~x~ values is ~(100, 1000, 10000, 100000,
1000000)~.

It would not have been to hard to generate all those read/write
sequences, but I wonder, how would I generate all possible codes to
check the outcomes?

**** Part 2

When the two serialized procedures are used:
#+begin_src scheme :exports both :results output
(define x 10)
(define s (make-serializer))
(parallel-execute (s (lambda () (set! x (* x x))))
                  (s (lambda () (set! x (* x x x)))))
#+end_src

Only two outcomes are left: when the first function runs, and when the
second function runs, which is either \(100^3\), or \(1000^2\), which is
both 1000000.

*** DONE Exercise 3.41 Better protected account
    CLOSED: [2020-01-02 Thu 10:02]

I don't think that Ben's concern is valid. It may indeed happen that
the value of ~balance~ changes between the time when the value is
queried and the time it is returned, however wrapping a value in a
protective serialized lambda does not solve this issue. Rather the
whole call to the ~balance~ getter would need to be serialized.

*** DONE Exercise 3.42 Saving on serializers
    CLOSED: [2020-01-02 Thu 10:35]

This exercise seems to be dealing with a thing called reentrancy,
which seems to be quite implementation-dependent. The version I wrote
would be asking to acquire the mutex any way, so I don't see how a
race condition can appear here.

#+begin_src scheme :exports both :results value
<<parallel-execute>>
<<make-serializer>>
<<make-parallel-account>>
 (let ((acc (make-account 100))) 
   (parallel-execute 
     (lambda () (thread-sleep! 0.1) ((acc 'withdraw) 10)) 
     (lambda () ((acc 'withdraw) 20))) 
   (acc 'balance)) 

#+end_src

#+RESULTS:
: 70

*** DONE Exercise 3.43 Multiple serializations
    CLOSED: [2020-01-02 Thu 11:33]

#+begin_src scheme :exports both :results output :noweb-ref unsafe-exchange
  (define (exchange account1 account2)
    (let ((difference (- (account1 'balance)
			 (account2 'balance))))
      ((account1 'withdraw) difference)
      ((account2 'deposit) difference)))
#+end_src

It seems to be quite obvious that this code works correctly in a
single-threaded case. Any inconsistency would arise from an incorrect
order of mutations, but with one thread, this never happens.

For the parallel case, the following erroneous behaviour may happen:

#+begin_src plantuml :exports both :file exercise-3-43-1.png
@startuml
skinparam monochrome true
actor "   Peter   " as Peter

entity "   Account 1   " as acc1
entity "   Account 2   " as acc2
entity "   Account 3   " as acc3
actor "   Paul   "  as Paul
rnote over acc1: $10
rnote over acc2: $20
rnote over acc3: $30
rnote over Peter: Exchange\n 1 and 2
rnote over Paul: Exchange\n 2 and 3
Peter -> acc1: balance
acc1 -> Peter: 10
Peter -> acc2: balance
acc2 -> Peter: 20
rnote over Peter: difference=-10


Paul -> acc2: balance
acc2 -> Paul: 20
Paul -> acc3: balance
acc3 -> Paul: 30
rnote over Paul: difference=-10


Peter -> acc1: withdraw -10
rnote over acc1: $20

Paul -> acc2: withdraw -10
rnote over acc2: $30
Paul -> acc3: deposit -10
rnote over acc3: $20

Peter -> acc2: deposit -10
rnote over acc2: $20

@enduml
#+end_src

#+RESULTS:
[[file:exercise-3-43.png]]

Even though every balance query is immediately followed by a response,
still, incorrect ordering of mutations leads to the final accounts'
states as $20, $20, $20.

A fully non-synchronized version would be more disastrous:
#+begin_src plantuml :exports both :file exercise-3-43-2.png
@startuml
skinparam monochrome true
actor "   Peter   " as Peter

entity "   Account 1   " as acc1
entity "   Account 2   " as acc2
entity "   Account 3   " as acc3
actor "   Paul   "  as Paul
rnote over acc1: $10
rnote over acc2: $20
rnote over acc3: $30
rnote over Peter: Exchange\n 1 and 2
rnote over Paul: Exchange\n 2 and 3
Peter -> acc1: balance
acc1 -> Peter: 10
Peter -> acc2: balance

Paul -> acc2: balance
acc2 -> Paul: 20
Paul -> acc3: balance
acc3 -> Paul: 30
rnote over Paul: difference=-10


acc2 -> Peter: 20
rnote over Peter: difference=-10
Peter -> acc1: withdraw -10
rnote over acc1: $20


Peter -> acc2: deposit -10
Paul -> acc2: withdraw -10
rnote over acc2: $30
rnote over acc2: $10


Paul -> acc3: deposit -10
rnote over acc3: $20

@enduml
#+end_src

#+RESULTS:
[[file:exercise-3-43-2.png]]

Depending on the order of writing the balance variable in the account
2, the value may be wrong in different ways.

*** DONE Exercise 3.44 Transfer money
    CLOSED: [2020-01-02 Thu 11:40]

I think that Louis is wrong here. The problem with exchanging amounts
is that the next value of account A depends on the previous value of
an account B. However, in this case the dependency is not so
strict. The next value of an account A only depends on the amount
~amount~. The dependency would be back though, if there may be not
enough money on the account B. Then the operation could fail,
depending on the order of execution.

*** DONE Exercise 3.45 new plus old serializers
    CLOSED: [2020-01-02 Thu 11:46]

The problem with Louis' suggestion is that the same mutex would be
acquired twice. That is, we would attempt to serialize an already
serialized procedure, and would get in a deadlock. 

That is, we would have something like ~(balance-serializer
(balance-serializer withdraw))~, which would attempt to obtain the
same lock twice, and thus will wait forever.

*** DONE Exercise 3.46 broken test-and-set!
    CLOSED: [2020-01-02 Thu 11:56]

#+begin_src plantuml :exports both :file exercise-3-46.png
@startuml
skinparam monochrome true
control "  Process 1   " as p1

entity "   Mutex   " as m
control "  Process 2   "  as p2
rnote over m: false
p1 -> m: test-and-set!
p2 -> m: test-and-set!
rnote over m: set-car! cell true
rnote over m: set-car! cell true
rnote over m: true
m -> p1: false
m -> p2: false
rnote over p1: acquired
rnote over p2: acquired

@enduml
#+end_src

#+RESULTS:
[[file:exercise-3-46.png]]

*** DONE Exercise 3.47 semaphores
    CLOSED: [2020-01-03 Fri 12:59]
**** DONE a: In terms of mutexes
     CLOSED: [2020-01-03 Fri 12:38]

#+begin_src scheme :exports both :results output
  <<parallel-execute>>
  <<make-serializer>>
    (define (make-semaphore max-count)
      (let ((count 0)
	    (mutex (make-mutex)))
	(define (the-semaphore op)
	  (cond ((eq? op 'acquire)
		 (begin
		   (mutex 'acquire)
		   (if (= count max-count)
		       (begin
			 (mutex 'release)
			 (the-semaphore 'acquire))
		       (begin
			 (set! count (+ 1 count))
			 (mutex 'release)))))
		((eq? op 'release)
		 (begin
		   (mutex 'acquire)
		   (set! count (max 0 (- count 1)))
		   (mutex 'release)
		   'released)))) the-semaphore))

  (define test-semaphore (make-semaphore 2))
  (parallel-execute 
       (lambda () (test-semaphore 'acquire) 
	     (thread-sleep! 3) 
	     (show #t "Hello1: " (current-second) "\n")
	     (test-semaphore 'release)) 
       (lambda () (test-semaphore 'acquire) 
	     (thread-sleep! 3) 
             (show #t "Hello2: " (current-second) "\n")
	     (test-semaphore 'release))
       (lambda () (test-semaphore 'acquire) 
	     (thread-sleep! 3) 
             (show #t "Hello3: " (current-second) "\n")
	     (test-semaphore 'release)))

#+end_src

#+RESULTS:
: Hello2: Hello1: 1578026228.6750461578026228.675087
: 
: Hello3: 1578026231.676726

On my machine, the output from threads 1 and 2 is interleaved, while
the output from thread 3 is separate. I consider this to be a proof of
the fact that my code works as expected.

**** DONE b: In terms of test-and-set! operations
     CLOSED: [2020-01-03 Fri 12:59]

#+begin_src scheme :exports both :results output
  <<parallel-execute>>
  <<make-serializer>>
    (define (make-semaphore max-count)
      (let ((count 0)
            (cell (list false)))
	(define (the-semaphore op)
	  (cond ((eq? op 'acquire)
		 (begin
                   (if (test-and-set! cell)
                       (the-semaphore 'acquire))
		   (if (= count max-count)
		       (begin
			 (clear! cell)
			 (the-semaphore 'acquire))
		       (begin
			 (set! count (+ 1 count))
			 (clear! cell)))))
		((eq? op 'release)
		 (begin
                   (if (test-and-set! cell)
                       (the-semaphore 'release))
		   (set! count (max 0 (- count 1)))
		   (clear! cell)
		   'released)))) the-semaphore))

  (define test-semaphore (make-semaphore 2))
  (parallel-execute 
       (lambda () (test-semaphore 'acquire) 
	     (thread-sleep! 1) 
	     (show #t "Hello1: " (current-second) "\n")
	     (test-semaphore 'release)) 
       (lambda () (test-semaphore 'acquire) 
	     (thread-sleep! 1) 
             (show #t "Hello2: " (current-second) "\n")
	     (test-semaphore 'release))
       (lambda () (test-semaphore 'acquire) 
	     (thread-sleep! 1) 
             (show #t "Hello3: " (current-second) "\n")
	     (test-semaphore 'release)))

#+end_src

#+RESULTS:
: Hello1: Hello2: 1578027561.9465251578027561.946571
: 
: Hello3: 1578027562.950841

Also seems to be working fine.

*** DONE Exercise 3.48 serialized-exchange deadlock
    CLOSED: [2020-01-03 Fri 13:30]

#+begin_src scheme :exports both :results output
  (define (make-account-and-serializer balance)
    (define (withdraw amount)
      (if (>= balance amount)
	  (begin (set! balance (- balance amount))
		 balance)
	  "Insufficient funds"))
    (define (deposit amount)
      (set! balance (+ balance amount))
      balance)
    (let ((balance-serializer (make-serializer)))
      (define (dispatch m)
	(cond ((eq? m 'withdraw) withdraw)
	      ((eq? m 'deposit) deposit)
	      ((eq? m 'balance) balance)
	      ((eq? m 'serializer) balance-serializer)
	      (else (error "Unknown request: MAKE-ACCOUNT" m))))
      dispatch))

  (define (deposit account amount)
    (let ((s (account 'serializer))
	  (d (account 'deposit)))
      ((s d) amount)))
  (define (exchange account1 account2)
    (let ((difference (- (account1 'balance)
			 (account2 'balance))))
      ((account1 'withdraw) difference)
      ((account2 'deposit) difference)))
  (define (serialized-exchange account1 account2)
    (let ((serializer1 (account1 'serializer))
	  (serializer2 (account2 'serializer)))
      ((serializer1 (serializer2 exchange))
       account1
       account2)))

#+end_src

The following code will thus get stuck in a deadlock:

#+begin_src scheme :exports both :results output
(define a1 (make-account-and-serializer 20))
(define a2 (make-account-and-serializer 30))

(parallel-execute
  (lambda () (serialized-exchange a1 a2))
  (lambda () (serialized-exchange a2 a1)))
#+end_src

We add serial numbers to resources:

#+begin_src scheme :exports both :results output
    <<make-serializer>>
    <<parallel-execute>>
    (define (make-account-and-serializer balance serial)
      (define (withdraw amount)
	(if (>= balance amount)
	    (begin (set! balance (- balance amount))
		   balance)
	    "Insufficient funds"))
      (define (deposit amount)
	(set! balance (+ balance amount))
	balance)
      (let ((balance-serializer (make-serializer)))
	(define (dispatch m)
	  (cond ((eq? m 'withdraw) withdraw)
		((eq? m 'deposit) deposit)
		((eq? m 'balance) balance)
		((eq? m 'serializer) balance-serializer)
                ((eq? m 'order) serial)
		(else (error "Unknown request: MAKE-ACCOUNT" m))))
	dispatch))

    (define (deposit account amount)
      (let ((s (account 'serializer))
	    (d (account 'deposit)))
	((s d) amount)))

    (define (exchange account1 account2)
      (let ((difference (- (account1 'balance)
			   (account2 'balance))))
	((account1 'withdraw) difference)
	((account2 'deposit) difference)))

    (define (serialized-exchange account1 account2)
      (let ((serializer1 (account1 'serializer))
	    (serializer2 (account2 'serializer)))
	(if (< (account1 'order) (account2 'order))
	    ((serializer1 (serializer2 exchange))
	     account1
	     account2)
	    ((serializer2 (serializer1 exchange))
	     account2
	     account1))))
  (define a1 (make-account-and-serializer 20 1))
  (define a2 (make-account-and-serializer 30 2))

(show #t "Balance start: " (a1 'balance) " " (a2 'balance) "\n")

  (parallel-execute
    (lambda () (serialized-exchange a1 a2))
    (lambda () (serialized-exchange a2 a1)))
(show #t "Balance end: " (a1 'balance) " " (a2 'balance) "\n")
#+end_src

#+RESULTS:
: Balance start: 20 30
: Balance end: 20 30

Exchange seems to go fine.

This works, because if mutexes are ordered, both all parallel
processes will try to access the same mutex first.

*** DONE Exercise 3.49 When numbering accounts doesn't work
    CLOSED: [2020-01-03 Fri 13:41]
The case suggested by the hint of the exercise is the following:
Suppose we need to transfer the money from account a1 to some other
account, that is recorded as a list inside account a1, and then remove
this "pending transfer" from the list of transfers of account a1. To
do this, we would need to first lock the account a1 to get the pointer
to account a2, and _then_ lock a2. However, it may very well be that
the account a2 has a smaller serial number than a1. 

We could, however, unlock a1, lock a2, then lock a1 again, and check
that the pending transaction from a1 to a2 is still needed.

*** Streams common

#+begin_src scheme :exports both :results output :noweb-ref streams-common
  (define-syntax cons-stream
    (syntax-rules ()
      ((cons-stream a b) (cons a (delay b)))))
  (define (stream-car stream) (car stream))
  (define (stream-cdr stream) (force (cdr stream)))
  (define (stream-ref s n)
    (if (= n 0)
	(stream-car s)
	(stream-ref (stream-cdr s) (- n 1))))

  (define (stream-map proc s)
    (if (stream-null? s)
	the-empty-stream
	(cons-stream (proc (stream-car s))
		     (stream-map proc (stream-cdr s)))))
  (define stream-null? null?)
  (define the-empty-stream '())
  (define (stream-for-each proc s)
    (if (stream-null? s)
	'done
	(begin (proc (stream-car s))
	       (stream-for-each proc (stream-cdr s)))))
  (define (display-stream s)
    (stream-for-each display-line s))

  (define (display-line x)
    (newline)
    (display x))
  (define (stream-enumerate-interval low high)
    (if (> low high)
	the-empty-stream
	(cons-stream
	 low
	 (stream-enumerate-interval (+ low 1) high))))
  (define (stream-filter pred stream)
    (cond ((stream-null? stream) the-empty-stream)
	  ((pred (stream-car stream))
	   (cons-stream (stream-car stream)
			(stream-filter pred
				       (stream-cdr stream))))
	  (else (stream-filter pred (stream-cdr stream)))))

#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
(display (cons-stream 2 3))
(newline)
(display (stream-car (cons-stream 2 3)))
(newline)
(display (stream-cdr (cons-stream 2 3)))
(newline)
(display-stream (cons-stream 2 (cons-stream 3 the-empty-stream)))
#+end_src

#+RESULTS:
: (2 (#f . #<procedure #f>) promise)
: 2
: 3
: 
: 2
: 3

NOTE: As far as I understand, ~(delay)~ and ~(force)~ are using
memoization inside by default in R^7 RS, so we needn't care about it
ourselves.

*** DONE Exercise 3.50 stream-map multiple arguments
    CLOSED: [2020-01-03 Fri 21:18]

#+begin_src scheme :exports both :results output :noweb-ref streams-multimap
  (define (stream-map proc . argstreams)
    (if (stream-null? (car argstreams))
	the-empty-stream
	(cons-stream
	 (apply proc (map stream-car argstreams))
	 (apply stream-map
		(cons proc (map stream-cdr argstreams))))))

#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
(display-stream (stream-map list (cons-stream 'one the-empty-stream)
                                 (cons-stream 'two the-empty-stream)))

#+end_src

#+RESULTS:
: 
: (one two)

Apparently, works.

*** DONE Exercise 3.51 stream-show
    CLOSED: [2020-01-03 Fri 21:28]

#+begin_src scheme :exports both :results output
  <<streams-common>>
  (define (show x)
    (display-line x)
    x)
  (define x (stream-map show (stream-enumerate-interval 0 10)))
  (stream-ref x 5)
  (newline) (display "next call to stream-ref:")
  (stream-ref x 7)
  (stream-ref x 7)
#+end_src

#+RESULTS:
#+begin_example

0
1
2
3
4
5
next call to stream-ref:
6
7
#+end_example

Why does it only print 6 and 7 on the second call? The answer is --
memoization. Since ~force~ already knows the result of calls to
~(stream-ref 5)~, it doesn't call ~show~ on them again.

*** DONE Exercise 3.52 streams with mind-boggling
    CLOSED: [2020-01-03 Fri 22:17]

#+begin_src scheme :exports both :results output
<<streams-common>>
  (define sum 0)
  (show #t "debug1: " sum "\n")
  (define (accum x)
    (set! sum (+ x sum))
    sum)
  (show #t "debug2: " sum "\n")
  (define seq (stream-map accum (stream-enumerate-interval 1 20)))
  (show #t "debug3 (stream-map forces a stream once): " sum "\n")
  (define y (stream-filter even? seq))
  (show #t "debug4 1+2+3: " sum "\n")
  (define z (stream-filter (lambda (x) (= (remainder x 5) 0))
			   seq))
  (show #t "debug5 adds 4, as all lower are already evaluated: " sum "\n")
  (stream-ref y 7)
  (show #t "debug6 adds sums that are even up to 20: " sum "\n")
  (display-stream z)
  (show #t "\ndebug7: " sum "\n")
#+end_src

#+RESULTS:
#+begin_example
debug1: 0
debug2: 0
debug3: 1
debug4: 6
debug5: 10
debug6: 136

10
15
45
55
105
120
190
210
debug7: 210
#+end_example

#+begin_src scheme :exports both :results output
(define delay #f)
(define force #f)
(define-syntax delay
  (syntax-rules ()
   ((delay x) (lambda () x))))
(define (force delayed-object) (delayed-object))
<<streams-common>>
  (define sum 0)
  (show #t "debug1: " sum "\n")
  (define (accum x)
    (set! sum (+ x sum))
    sum)
  (show #t "debug2: " sum "\n")
  (define seq (stream-map accum (stream-enumerate-interval 1 20)))
  (show #t "debug3: " sum "\n")
  (define y (stream-filter even? seq))
  (show #t "debug4: " sum "\n")
  (define z (stream-filter (lambda (x) (= (remainder x 5) 0))
			   seq))
  (show #t "debug5: " sum "\n")
  (stream-ref y 7)
  (show #t "debug6: " sum "\n")
  (display-stream z)
  (show #t "\ndebug7: " sum "\n")
#+end_src

#+RESULTS:
#+begin_example
debug1: 0
debug2: 0
debug3: 1
debug4: 6
debug5: 15
debug6: 162

15
180
230
305
debug7: 362
#+end_example

The difference here, again, lies in memoization. In the first example,
sum is only evaluated once for every number from 1 to 20, in the
second, every time ~force~ is called. Every call to ~force~ adds to
the ~sum~. I find it hard to find when exactly things are added to the
sum. This can be debugged by adding a print to the ~accum~ procedure,
but the general rule seems to be: don't use mutation together with
lazy lists.

*** Some more tools for streams
#+begin_src scheme :exports both :results output :noweb-ref streams-2
  (define (add-streams s1 s2)
    (stream-map + s1 s2))
  (define ones (cons-stream 1 ones))
  (define zeros (cons-stream 0 zeros))
  (define integers (cons-stream 1 (add-streams ones integers)))
  (define (scale-stream stream factor)
    (stream-map (lambda (x) (* x factor)) stream))

#+end_src
*** DONE Exercise 3.53 stream power of two
    CLOSED: [2020-01-03 Fri 22:40]

Before running the code, I make a hypothesis that the stream
represents powers of two, because each element is the previous one,
doubled. 

#+begin_src scheme :exports both :results value
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
(define s (cons-stream 1 (add-streams s s)))
(stream-ref s 6)
#+end_src

#+RESULTS:
: 64

*** DONE Exercise 3.54 mul-streams
    CLOSED: [2020-01-03 Fri 22:47]

#+begin_src scheme :exports both :results output :noweb-ref streams-mul
  (define (mul-streams s1 s2)
    (stream-map * s1 s2))
#+end_src

#+begin_src scheme :exports both :results value
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-mul>>
(define factorials 
  (cons-stream 1 (mul-streams factorials integers)))
(stream-ref factorials 5)
#+end_src

#+RESULTS:
: 120

*** DONE Exercise 3.55 streams partial-sums
    CLOSED: [2020-01-03 Fri 23:05]

#+begin_src scheme :exports both :results output :noweb-ref streams-partial-sums
(define (partial-sums s)
  (define ps (cons-stream (stream-car s) (add-streams ps (stream-cdr s))))
  ps)
#+end_src

#+begin_src scheme :exports both :results output value
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
(define ps (partial-sums integers))
(list (stream-ref ps 0)
(stream-ref ps 1)
(stream-ref ps 2)
(stream-ref ps 3)
(stream-ref ps 4))

#+end_src

#+RESULTS:
| 1 | 3 | 6 | 10 | 15 |

*** DONE Exercise 3.56 Hamming's streams-merge
    CLOSED: [2020-01-03 Fri 23:26]

#+begin_src scheme :exports both :results output :noweb-ref streams-merge
          (define (merge s1 s2)
            (cond ((stream-null? s1) s2)
                  ((stream-null? s2) s1)
                  (else
                   (let ((s1car (stream-car s1))
                         (s2car (stream-car s2)))
                     (cond ((< s1car s2car)
                            (cons-stream s1car (merge (stream-cdr s1) s2)))
                           ((> s1car s2car)
                            (cons-stream s2car (merge s1 (stream-cdr s2))))
                           (else
                            (cons-stream s1car
                                         (merge (stream-cdr s1)
                                                (stream-cdr s2)))))))))

#+end_src

#+begin_src scheme :exports both :results value
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-merge>>
(define S (cons-stream 1 (merge (scale-stream S 2)
                                (merge (scale-stream S 3)
                                       (scale-stream S 5)))))
(stream-ref S 5)
#+end_src

#+RESULTS:
: 6

*** DONE Exercise 3.57 exponential additions fibs
    CLOSED: [2020-01-03 Fri 23:36]

The definition of ~fibs~ is the following:

#+begin_src scheme :exports both :results output
  (define fibs
    (cons-stream 0
		 (cons-stream 1
			      (add-streams (stream-cdr fibs)
					   fibs))))
#+end_src

With memoization, every step just requires \(O(n)\) additions, because
every ~stream-cdr~ would only add two already computed values.

Without memoization, every step would require computing all previous
values of the Fibonacci sequence from scratch. It is not hard to
notice that the element number N would require computing numbers N-1
and N-2, so every step would roughly double the number
operations. Thus the total number would be \(O(2^n)\).

*** DONE Exercise 3.58 Cryptic stream
    CLOSED: [2020-01-03 Fri 23:50]
This cryptic stream approximates a rational fraction by a decimal
(radix) one. 

#+begin_src scheme :exports both :results output 
  <<streams-common>>
  (define (expand num den radix)
    (cons-stream
     (quotient (* num radix) den)
     (expand (remainder (* num radix) den) den radix)))
  (do ((i 0 (+ i 1)))
      ((= i 5) #t)
    (show #t (stream-ref (expand 1 7 10) i)))
  (newline)
  (show #t (/ 1.0 7.0) "\n")
  (do ((i 0 (+ i 1)))
      ((= i 5) #t)
    (show #t (stream-ref (expand 3 8 10) i)))
  (newline)
  (show #t (/ 3.0 8.0) "\n")

#+end_src

#+RESULTS:
: 14285
: 0.14285714285714285
: 37500
: 0.375

*** DONE Exercise 3.59 power series
    CLOSED: [2020-01-04 Sat 09:58]
**** DONE integrate series
     CLOSED: [2020-01-04 Sat 09:49]
#+begin_src scheme :exports both :results output :noweb-ref streams-integrate-series
(define (div-streams s1 s2)
  (stream-map / s1 s2))

(define (integrate-series s)
 (div-streams s integers))

#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-integrate-series>>

(define test (integrate-series ones))

(do ((i 0 (+ i 1)))
      ((= i 5) #t)
    (show #t (stream-ref test i) " "))

#+end_src

#+RESULTS:
: 1 1/2 1/3 1/4 1/5 

**** DONE exponential series
     CLOSED: [2020-01-04 Sat 09:58]

#+begin_src scheme :exports both :results output :noweb-ref streams-sin-cos
(define exp-series
  (cons-stream 1 (integrate-series exp-series)))
(define cosine-series
  (cons-stream 1 (integrate-series (scale-stream sine-series -1))))
(define sine-series
  (cons-stream 0 (integrate-series cosine-series)))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-integrate-series>>
<<streams-sin-cos>>

(do ((i 0 (+ i 1)))
      ((= i 5) #t)
    (show #t (stream-ref cosine-series i) " "))
(newline)
(do ((i 0 (+ i 1)))
      ((= i 5) #t)
    (show #t (stream-ref sine-series i) " "))
#+end_src

#+RESULTS:
: 1 0 -1/2 0 1/24 
: 0 1 0 -1/6 0 

*** DONE Exercise 3.60 mul-series
    CLOSED: [2020-01-04 Sat 11:07]
Let's write out a formula first:

\(S = \sum_{i=0}^{\infty}a_i \cdot \sum_{j=0}^{\infty}b_j = a_0 \cdot b_0 + b_0 \cdot
\sum_{i=1}^{\infty}a_i + \sum_{i=0}^{\infty}a_i \cdot \sum_{j=1}^{\infty}b_j\)

#+begin_src scheme :exports both :results output :noweb-ref streams-mul-series
(define (mul-series s1 s2)
  (cons-stream (* (stream-car s1) (stream-car s2))
                (add-streams (scale-stream (stream-cdr s1) (stream-car s2)) 
                             (mul-series s1 (stream-cdr s2)))))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-integrate-series>>
<<streams-sin-cos>>
<<streams-mul-series>>
<<streams-partial-sums>>
(define sum-of-sine-and-cosine
 (partial-sums (add-streams (mul-series sine-series sine-series)
                            (mul-series cosine-series cosine-series))))
(do ((i 0 (+ i 1)))
      ((= i 10) #t)
    (show #t (inexact (stream-ref sum-of-sine-and-cosine i)) " "))

#+end_src

#+RESULTS:
: 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 

Converges to 1 quite fast.

*** DONE Exercise 3.61 power-series-inversion
    CLOSED: [2020-01-04 Sat 13:13]
#+begin_src scheme :exports both :results output :noweb-ref streams-invert-unit-series
#;(define (invert-unit-series S)
  (define x (cons-stream 1
                         (mul-series
                          (scale-stream (cons-stream 0 (stream-cdr S)) -1)
                          x)))
  x)
(define (invert-unit-series S)
    (if (not (= 1 (stream-car S)))
        (error "First term must be 1 -- INVERT-UNIT-SERIES" (stream-car S))        
        (let ((Sr (stream-cdr S)))
            (define X 
                (cons-stream 
                    1 
                    (mul-series 
                        (scale-stream Sr -1)
                        X)))
            X)))

#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-integrate-series>>
<<streams-sin-cos>>
<<streams-mul-series>>
<<streams-partial-sums>>
<<streams-invert-unit-series>>

(define test (partial-sums (mul-series ones (invert-unit-series ones))))
#;("Should give a series with partial sums converging to 1")
(do ((i 0 (+ i 1)))
      ((= i 10) #t)
    (show #t (inexact (stream-ref test i)) " "))

#+end_src

#+RESULTS:
: 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 

Okay, this exercise gave me hell of a lot of pain. Why on it is so
dependent on the implementation of ~mul-series~?

So this exercise has been solved with the help of the GitHub user
ypeels:
https://github.com/ypeels/sicp/blob/master/exercises/3.61-invert-unit-series.scm

*** DONE Exercise 3.62 div-series
    CLOSED: [2020-01-04 Sat 13:21]

#+begin_src scheme :exports both :results output :noweb-ref streams-div-series
(define (div-series s1 s2)
  (let* ((scale-factor (stream-car s2))
         (scaled-s2 (scale-stream s2 (/ 1 scale-factor)))
         (scaled-s1 (scale-stream s1 scale-factor))
         (inverted-s2 (invert-unit-series scaled-s2)))
   (mul-series scaled-s1 inverted-s2)))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-integrate-series>>
<<streams-sin-cos>>
<<streams-mul-series>>
<<streams-partial-sums>>
<<streams-invert-unit-series>>
<<streams-div-series>>

(define test (div-series ones exp-series))
#;("Should give a series with partial sums converging to 1")
(do ((i 0 (+ i 1)))
      ((= i 10) #t)
    (show #t (inexact (stream-ref test i)) " "))

#+end_src

#+RESULTS:
: 1.0 0.0 0.5 0.3333333333333333 0.375 0.36666666666666664 0.3680555555555556 0.3678571428571429 0.36788194444444444 0.36787918871252206 

Well, not sure this is correct, but it runs.

*** DONE Exercise 3.63 sqrt-stream
    CLOSED: [2020-01-04 Sat 20:32]
#+begin_src scheme :exports both :results output :noweb-ref streams-sqrt-stream
     (define (average x y)
       (/ (+ x y) 2))
  (define (sqrt-improve guess x)
    (average guess (/ x guess)))

  (define (sqrt-stream x)
    (cons-stream 1.0
		 (stream-map (lambda (guess)
			       (sqrt-improve guess x))
			     (sqrt-stream x))))
#+end_src

The problem with the second definition is that ~(sqrt-stream x)~, as
it is called each time, creates a new stream. Since this streams are
not ~eq?~, memoization doesn't work. In the first implementation, the
same ~guesses~ is used, and thus, calls to the lambda are cached
(memoized).

If ~delay~ didn't use memoization, performance would be same for both
implementations.
*** DONE Exercise 3.64 stream-limit
    CLOSED: [2020-01-06 Mon 09:38]

#+begin_src scheme :exports both :results output :noweb-ref streams-stream-limit
(define (stream-limit stream tolerance)
  (let ((a1 (stream-car stream))
        (a2 (stream-car (stream-cdr stream))))
    (if (< (abs (- a1 a2)) tolerance)
      a2
      (stream-limit (stream-cdr stream) tolerance))))

#+end_src

#+begin_src scheme :exports both :results output :noweb-ref streams-sqrt
  (define (sqrt x tolerance)
    (stream-limit (sqrt-stream x) tolerance))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-stream-limit>>
<<streams-sqrt-stream>>
<<streams-sqrt>>

(show #t "Test sqrt of 17: " (sqrt 17 0.001) "\n")

#+end_src

#+RESULTS:
: Test sqrt of 17: 4.123105625617805

Seems to be working. I copied some of the ~sqrt~-related code from the
earlier chapters instead of tangling, because it seems too slow.

*** DONE Exercise 3.65 approximating logarithm
    CLOSED: [2020-01-06 Mon 10:34]

First let's make sure that the pi-stream is working.

#+begin_src scheme :exports both :results output :noweb-ref streams-print-n
(define (stream-print-n stream n)
    (do ((i 0 (+ i 1)))
      ((= i n) #t)
    (display (stream-ref stream i))
    (display " ")))

#+end_src

#+begin_src scheme :exports both :results output :noweb-ref streams-pi-summands
     (define (pi-summands n)
       (cons-stream (/ 1.0 n)
                    (stream-map - (pi-summands (+ n 2)))))
     (define pi-stream
       (scale-stream (partial-sums (pi-summands 1)) 4))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-pi-summands>>
<<streams-print-n>>
(stream-print-n pi-stream 10)

#+end_src

#+RESULTS:
: 4.0 2.666666666666667 3.466666666666667 2.8952380952380956 3.3396825396825403 2.9760461760461765 3.2837384837384844 3.017071817071818 3.2523659347188767 3.0418396189294032 

Now let us do the same for the logarithm of 2.

#+begin_src scheme :exports both :results output :noweb-ref streams-log-summands
     (define (log-summands n)
       (cons-stream (/ 1.0 n)
                    (stream-map - (log-summands (+ n 1)))))
     (define log-stream
       (partial-sums (log-summands 1)))
#+end_src

#+begin_src scheme :exports both :results output :noweb-ref streams-euler-tableau
     (define (euler-transform s)
       (let ((s0 (stream-ref s 0))         
             (s1 (stream-ref s 1))         
             (s2 (stream-ref s 2)))        
         (cons-stream (- s2 (/ (square (- s2 s1))
                               (+ s0 (* -2 s1) s2)))
                      (euler-transform (stream-cdr s)))))
     (define (make-tableau transform s)
       (cons-stream s
                    (make-tableau transform
                                  (transform s))))
     (define (accelerated-sequence transform s)
       (stream-map stream-car
                   (make-tableau transform s)))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-print-n>>
<<streams-log-summands>>
<<streams-euler-tableau>>
(do ((i 0 (+ i 1)))
  ((= i 10) #t)
  (show #t (stream-ref (log-summands 1) i) " "))
(newline)
(stream-print-n log-stream 10)
(newline)
(stream-print-n (euler-transform log-stream) 10)
(newline)
(stream-print-n (accelerated-sequence euler-transform log-stream) 10)

#+end_src

#+RESULTS:
: 1.0 -0.5 0.3333333333333333 -0.25 0.2 -0.16666666666666666 0.14285714285714285 -0.125 0.1111111111111111 -0.1 
: 1.0 0.5 0.8333333333333333 0.5833333333333333 0.7833333333333332 0.6166666666666666 0.7595238095238095 0.6345238095238095 0.7456349206349207 0.6456349206349207 
: 0.7 0.6904761904761905 0.6944444444444444 0.6924242424242424 0.6935897435897436 0.6928571428571428 0.6933473389355742 0.6930033416875522 0.6932539682539683 0.6930657506744464 
: 1.0 0.7 0.6932773109243697 0.6931488693329254 0.6931471960735491 0.6931471806635636 0.6931471805604039 0.6931471805599445 0.6931471805599427 0.6931471805599454 

The first stream seems to be converging quite slowly, needing about 10
steps for 0.01 precision. The "accelerated" sequence converges in
three steps, which seems to be super fast. Proper convergence analysis
would require a bit more of a mathematical analysis. 

*** DONE Exercise 3.66 lazy pairs
    CLOSED: [2020-01-06 Mon 22:55]

#+begin_src scheme :exports both :results output :noweb-ref streams-interleave
  (define (interleave s1 s2)
    (if (stream-null? s1)
	s2
	(cons-stream (stream-car s1)
		     (interleave s2 (stream-cdr s1)))))
#+end_src
  
#+begin_src scheme :exports both :results output :noweb-ref streams-pairs
  (define (pairs s t)
    (cons-stream
     (list (stream-car s) (stream-car t))
     (interleave
      (stream-map (lambda (x) (list (stream-car s) x))
		  (stream-cdr t))
      (pairs (stream-cdr s) (stream-cdr t)))))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-print-n>>
<<streams-interleave>>
<<streams-pairs>>

(stream-print-n (pairs integers integers) 100)

#+end_src

#+RESULTS:
: (1 1) (1 2) (2 2) (1 3) (2 3) (1 4) (3 3) (1 5) (2 4) (1 6) (3 4) (1 7) (2 5) (1 8) (4 4) (1 9) (2 6) (1 10) (3 5) (1 11) (2 7) (1 12) (4 5) (1 13) (2 8) (1 14) (3 6) (1 15) (2 9) (1 16) (5 5) (1 17) (2 10) (1 18) (3 7) (1 19) (2 11) (1 20) (4 6) (1 21) (2 12) (1 22) (3 8) (1 23) (2 13) (1 24) (5 6) (1 25) (2 14) (1 26) (3 9) (1 27) (2 15) (1 28) (4 7) (1 29) (2 16) (1 30) (3 10) (1 31) (2 17) (1 32) (6 6) (1 33) (2 18) (1 34) (3 11) (1 35) (2 19) (1 36) (4 8) (1 37) (2 20) (1 38) (3 12) (1 39) (2 21) (1 40) (5 7) (1 41) (2 22) (1 42) (3 13) (1 43) (2 23) (1 44) (4 9) (1 45) (2 24) (1 46) (3 14) (1 47) (2 25) (1 48) (6 7) (1 49) (2 26) (1 50) (3 15) (1 51) 

The logic behind the ordering can be seen from the kind of a
"probabilistic analysis". Let's imagine a table with columns indexed
by the elements of the first stream, and rows indexed by the second
stream. Every call to "interleave" takes a row of a table, and another
instance of the "pairs". This means that the frequency, with which
elements of every row appear in the output is \(2^{^}{-n}\), where n is
the number of the row. Therefore the number of a pair (a,b) should be
something like \(b \cdot a^{n} \).

*** DONE Exercise 3.67 all possible pairs
    CLOSED: [2020-01-06 Mon 23:09]

Seems not too hard. Just add in one more interleave.

#+begin_src scheme :exports both :results output :noweb-ref streams-pairs-full
  (define (pairs s t)
    (cons-stream
     (list (stream-car s) (stream-car t))
     (interleave
      (stream-map (lambda (x) (list (stream-car s) x))
		  (stream-cdr t))
      (interleave
        (stream-map (lambda (x) (list x (stream-car t)))
		  (stream-cdr s))
        (pairs (stream-cdr s) (stream-cdr t))))))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-print-n>>
<<streams-interleave>>
<<streams-pairs-full>>

(stream-print-n (pairs integers integers) 100)

#+end_src

#+RESULTS:
: (1 1) (1 2) (2 1) (1 3) (2 2) (1 4) (3 1) (1 5) (2 3) (1 6) (4 1) (1 7) (3 2) (1 8) (5 1) (1 9) (2 4) (1 10) (6 1) (1 11) (3 3) (1 12) (7 1) (1 13) (2 5) (1 14) (8 1) (1 15) (4 2) (1 16) (9 1) (1 17) (2 6) (1 18) (10 1) (1 19) (3 4) (1 20) (11 1) (1 21) (2 7) (1 22) (12 1) (1 23) (5 2) (1 24) (13 1) (1 25) (2 8) (1 26) (14 1) (1 27) (4 3) (1 28) (15 1) (1 29) (2 9) (1 30) (16 1) (1 31) (6 2) (1 32) (17 1) (1 33) (2 10) (1 34) (18 1) (1 35) (3 5) (1 36) (19 1) (1 37) (2 11) (1 38) (20 1) (1 39) (7 2) (1 40) (21 1) (1 41) (2 12) (1 42) (22 1) (1 43) (4 4) (1 44) (23 1) (1 45) (2 13) (1 46) (24 1) (1 47) (8 2) (1 48) (25 1) (1 49) (2 14) (1 50) (26 1) (1 51) 

*** DONE Exercise 3.68 pairs-louis
    CLOSED: [2020-01-06 Mon 23:26]

#+begin_src scheme :exports both :results output :noweb-ref streams-pairs-louis
  (define (pairs s t)
    (interleave
      (stream-map (lambda (x) (list (stream-car s) x))
		  t)
      (pairs (stream-cdr s) (stream-cdr t))))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-print-n>>
<<streams-interleave>>
<<streams-pairs-louis>>

(stream-print-n (pairs integers integers) 30)

#+end_src

#+RESULTS:
: ERROR: out of stack space
: > 

This is expected. Remember, the second argument to ~cons-stream~ is
not evaluated, it's delayed. If we don't separate the first pair from
the rest, ~interleave~ would run indefinitely.

*** DONE Exercise 3.69 triples
    CLOSED: [2020-01-07 Tue 11:00]

#+begin_src scheme :exports both :results output :noweb-ref streams-triples
  (define (triples s t u)
    (cons-stream
     (list (stream-car s) (stream-car t) (stream-car u))
     (interleave
      (stream-map (lambda (x) (cons (stream-car s) x))
		  (pairs (stream-cdr t) (stream-cdr u)))
      (triples (stream-cdr s) (stream-cdr t) (stream-cdr u)))))
#+end_src

#+RESULTS:

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-print-n>>
<<streams-interleave>>
<<streams-pairs>>
<<streams-triples>>

(stream-print-n 
(stream-filter 
       (lambda (triple) 
           (let ((i (car triple))
                 (j (cadr triple))
                 (k (caddr triple)))
            (= (* k k) (+ (* i i) (* j j)))))
(triples integers integers integers))
    7)

#+end_src

#+RESULTS:
: (3 4 5) (6 8 10) (5 12 13) (9 12 15) (8 15 17) (12 16 20) 

Seems to be working fine. 

*** DONE Exercise 3.70 merge-weighted
    CLOSED: [2020-01-07 Tue 11:58]

#+begin_src scheme :exports both :results output :noweb-ref streams-merge-weighted
  (define (merge-weighted s1 s2 weight)
    (cond ((stream-null? s1) s2)
	  ((stream-null? s2) s1)
	  (else
	   (let ((s1car (stream-car s1))
		 (s2car (stream-car s2)))
	     (cond ((< (weight s1car) (weight s2car))
		    (cons-stream s1car (merge-weighted (stream-cdr s1) s2 weight)))
		   ((> (weight s1car) (weight s2car))
		    (cons-stream s2car (merge-weighted s1 (stream-cdr s2) weight)))
		   (else
		    (cons-stream s1car
				 (merge-weighted (stream-cdr s1)
						 s2
                                                 weight))))))))

#+end_src

#+begin_src scheme :exports both :results output :noweb-ref streams-pairs-weighted
  (define (pairs-weighted s t weight)
    (cons-stream
     (list (stream-car s) (stream-car t))
     (merge-weighted
      (stream-map (lambda (x) (list (stream-car s) x))
		  (stream-cdr t))
      (pairs-weighted (stream-cdr s) (stream-cdr t) weight)
      weight)))
#+end_src

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-print-n>>
<<streams-interleave>>
<<streams-merge-weighted>>
<<streams-pairs-weighted>>

(stream-print-n 
  (pairs-weighted 
    integers
    integers
    (lambda (p) (+ (car p) (cadr p))))
 100)
(newline)
(stream-print-n 
  (pairs-weighted 
    (stream-filter (lambda (x) (and (not (= 0 (remainder x 2)))
                              (not (= 0 (remainder x 3)))
                              (not (= 0 (remainder x 5))))) integers)
    (stream-filter (lambda (x) (and (not (= 0 (remainder x 2)))
                              (not (= 0 (remainder x 3)))
                              (not (= 0 (remainder x 5))))) integers)
    (lambda (p) (+ (* 2 (car p)) (* 3 (cadr p) (* 5 (car p) (cadr p))))))
 100)

#+end_src

#+RESULTS:
: (1 1) (1 2) (1 3) (2 2) (1 4) (2 3) (1 5) (2 4) (3 3) (1 6) (2 5) (3 4) (1 7) (2 6) (3 5) (4 4) (1 8) (2 7) (3 6) (4 5) (1 9) (2 8) (3 7) (4 6) (5 5) (1 10) (2 9) (3 8) (4 7) (5 6) (1 11) (2 10) (3 9) (4 8) (5 7) (6 6) (1 12) (2 11) (3 10) (4 9) (5 8) (6 7) (1 13) (2 12) (3 11) (4 10) (5 9) (6 8) (7 7) (1 14) (2 13) (3 12) (4 11) (5 10) (6 9) (7 8) (1 15) (2 14) (3 13) (4 12) (5 11) (6 10) (7 9) (8 8) (1 16) (2 15) (3 14) (4 13) (5 12) (6 11) (7 10) (8 9) (1 17) (2 16) (3 15) (4 14) (5 13) (6 12) (7 11) (8 10) (9 9) (1 18) (2 17) (3 16) (4 15) (5 14) (6 13) (7 12) (8 11) (9 10) (1 19) (2 18) (3 17) (4 16) (5 15) (6 14) (7 13) (8 12) (9 11) (10 10) 
: (1 1) (1 7) (1 11) (1 13) (1 17) (7 7) (1 19) (1 23) (1 29) (7 11) (1 31) (7 13) (11 11) (1 37) (1 41) (1 43) (11 13) (7 17) (13 13) (1 47) (1 49) (7 19) (1 53) (11 17) (1 59) (7 23) (1 61) (13 17) (11 19) (1 67) (13 19) (17 17) (1 71) (1 73) (11 23) (7 29) (1 77) (17 19) (1 79) (7 31) (19 19) (13 23) (1 83) (1 89) (1 91) (17 23) (11 29) (1 97) (7 37) (19 23) (1 101) (11 31) (1 103) (13 29) (1 107) (7 41) (1 109) (23 23) (13 31) (1 113) (7 43) (1 119) (17 29) (1 121) (11 37) (7 47) (19 29) (1 127) (17 31) (7 49) (1 131) (1 133) (13 37) (19 31) (11 41) (1 137) (1 139) (23 29) (7 53) (11 43) (1 143) (13 41) (23 31) (1 149) (1 151) (17 37) (13 43) (11 47) (7 59) (29 29) (1 157) (1 161) (19 37) (7 61) (11 49) (1 163) (29 31) (1 167) (1 169) (17 41) 

Cannot say I understand what the second sequence signifies, but meh.

*** DONE Exercise 3.71 Ramanujan numbers
    CLOSED: [2020-01-07 Tue 12:49]

#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-print-n>>
<<streams-interleave>>
<<streams-merge-weighted>>
<<streams-pairs-weighted>>

(define cubic-pairs 
  (pairs-weighted 
    integers
    integers
    (lambda (p) (+ (expt (car p) 3) (expt (cadr p) 3)))))

(define sums-of-cubes 
   (stream-map (lambda (x) (+ (expt (car x) 3)
                          (expt (cadr x) 3)))
               cubic-pairs))
(stream-print-n sums-of-cubes 20)
(define (first-repetition s)
 (if (= (stream-car s) (stream-car (stream-cdr s)))
    s
    (first-repetition (stream-cdr s))))
(define (filter-repetitions s)
  (cons-stream (stream-car (first-repetition s)) 
               (filter-repetitions 
                 (stream-cdr (stream-cdr (first-repetition s))))))
(newline)
#;(display (stream-car (filter-repetitions s)))
(stream-print-n (filter-repetitions sums-of-cubes) 6)
#+end_src

#+RESULTS:
: 2 9 16 28 35 54 65 72 91 126 128 133 152 189 217 224 243 250 280 341 
: 1729 4104 13832 20683 32832 39312 


This solution is not very good, because it would fail to distinguish
the Ramanujan 2-numbers from the Ramanujan 4-numbers, but I am too
lazy to fix it.

*** TODO Exercise 3.72 Ramanujan 3-numbers
WARNING: The code below is quite slow. On my machine it takes more time than 
geiser's default ~geiser-connection-timeout~ permits. 
Refer to [[Setting chibi arguments. DANGEROUS]] for more information.
#+begin_src scheme :exports both :results output
<<streams-common>>
<<streams-multimap>>
<<streams-2>>
<<streams-partial-sums>>
<<streams-print-n>>
<<streams-interleave>>
<<streams-merge-weighted>>
<<streams-pairs-weighted>>

(define cubic-pairs 
  (pairs-weighted 
    integers
    integers
    (lambda (p) (+ (expt (car p) 3) (expt (cadr p) 3)))))

(define sumcubes
   (lambda (x) (+ (expt (car x) 3)
                          (expt (cadr x) 3))))
#;(stream-print-n sums-of-cubes 20)
(define (first-repetition s)
 (if (= (sumcubes (stream-car s)) 
        (sumcubes (stream-car (stream-cdr s))) 
        (sumcubes (stream-car (stream-cdr (stream-cdr s)))))
    s
    (first-repetition (stream-cdr s))))
(define (filter-repetitions s)
  (cons-stream (stream-car (first-repetition s)) 
               (filter-repetitions 
                 (stream-cdr (stream-cdr (stream-cdr (first-repetition s)))))))
(display " ")
(stream-print-n (filter-repetitions cubic-pairs) 1)
(newline)
#+end_src

#+RESULTS:
:  (167 436) 

*** TODO Figure 3.32



*** TODO Exercise 3.73

*** TODO Exercise 3.74

*** TODO Exercise 3.75

*** TODO Exercise 3.76

*** TODO Exercise 3.77

*** TODO Figure 3.35
*** TODO Exercise 3.78

*** TODO Exercise 3.79

*** TODO Exercise 3.80

*** TODO Exercise 3.81

*** TODO Exercise 3.82

** TODO Chapter 4: Metalinguistic Abstraction [0/79]

*** TODO Exercise 4.1

*** TODO Exercise 4.2

*** TODO Exercise 4.3

*** TODO Exercise 4.4

*** TODO Exercise 4.5

*** TODO Exercise 4.6

*** TODO Exercise 4.7

*** TODO Exercise 4.8

*** TODO Exercise 4.9

*** TODO Exercise 4.10

*** TODO Exercise 4.11

*** TODO Exercise 4.12

*** TODO Exercise 4.13

*** TODO Exercise 4.14

*** TODO Exercise 4.15

*** TODO Exercise 4.16

*** TODO Exercise 4.17

*** TODO Exercise 4.18

*** TODO Exercise 4.19

*** TODO Exercise 4.20

*** TODO Exercise 4.21

*** TODO Exercise 4.22

*** TODO Exercise 4.23

*** TODO Exercise 4.24

*** TODO Exercise 4.25

*** TODO Exercise 4.26

*** TODO Exercise 4.27

*** TODO Exercise 4.28

*** TODO Exercise 4.29

*** TODO Exercise 4.30

*** TODO Exercise 4.31

*** TODO Exercise 4.32

*** TODO Exercise 4.33

*** TODO Exercise 4.34

*** TODO Exercise 4.35

*** TODO Exercise 4.36

*** TODO Exercise 4.37

*** TODO Exercise 4.38

*** TODO Exercise 4.39

*** TODO Exercise 4.40

*** TODO Exercise 4.41

*** TODO Exercise 4.42

*** TODO Exercise 4.43

*** TODO Exercise 4.44

*** TODO Exercise 4.45

*** TODO Exercise 4.46

*** TODO Exercise 4.47

*** TODO Exercise 4.48

*** TODO Exercise 4.49

*** TODO Exercise 4.50

*** TODO Exercise 4.51

*** TODO Exercise 4.52

*** TODO Exercise 4.53

*** TODO Exercise 4.54

*** TODO Exercise 4.55

*** TODO Exercise 4.56

*** TODO Exercise 4.57

*** TODO Exercise 4.58

*** TODO Exercise 4.59

*** TODO Exercise 4.60

*** TODO Exercise 4.61

*** TODO Exercise 4.62

*** TODO Exercise 4.63

*** TODO Exercise 4.64

*** TODO Exercise 4.65

*** TODO Exercise 4.66

*** TODO Exercise 4.67

*** TODO Exercise 4.68

*** TODO Exercise 4.69

*** TODO Exercise 4.70

*** TODO Exercise 4.71

*** TODO Exercise 4.72

*** TODO Exercise 4.73
    
*** TODO Exercise 4.74

*** TODO Exercise 4.75

*** TODO Exercise 4.76

*** TODO Exercise 4.77

*** TODO Exercise 4.78

*** TODO Exercise 4.79

** TODO Chapter 5: Computing with Register Machines [0/52]

*** TODO Exercise 5.1

*** TODO Exercise 5.2

*** TODO Exercise 5.3

*** TODO Exercise 5.4

*** TODO Exercise 5.5

*** TODO Exercise 5.6

*** TODO Exercise 5.7

*** TODO Exercise 5.8

*** TODO Exercise 5.9

*** TODO Exercise 5.10

*** TODO Exercise 5.11

*** TODO Exercise 5.12

*** TODO Exercise 5.13

*** TODO Exercise 5.14

*** TODO Exercise 5.15

*** TODO Exercise 5.16

*** TODO Exercise 5.17

*** TODO Exercise 5.18

*** TODO Exercise 5.19

*** TODO Exercise 5.20

*** TODO Exercise 5.21

*** TODO Exercise 5.22

*** TODO Exercise 5.23

*** TODO Exercise 5.24

*** TODO Exercise 5.25

*** TODO Exercise 5.26

*** TODO Exercise 5.27

*** TODO Exercise 5.28

*** TODO Exercise 5.29

*** TODO Exercise 5.30

*** TODO Exercise 5.31

*** TODO Exercise 5.32

*** TODO Exercise 5.33

*** TODO Exercise 5.34

*** TODO Exercise 5.35

*** TODO Exercise 5.36

*** TODO Exercise 5.37

*** TODO Exercise 5.38

*** TODO Exercise 5.39

*** TODO Exercise 5.40

*** TODO Exercise 5.41

*** TODO Exercise 5.42

*** TODO Exercise 5.43

*** TODO Exercise 5.44

*** TODO Exercise 5.45

*** TODO Exercise 5.46

*** TODO Exercise 5.47

*** TODO Exercise 5.48

*** TODO Exercise 5.49

*** TODO Exercise 5.50

*** TODO Exercise 5.51

*** TODO Exercise 5.52

* Footnotes



[fn:1] This exercise took me 7 hours.
[fn:2] This exercise took me about 40 hours.

^ permalink raw reply	[relevance 1%]

* Bug: LaTeX export does not handle .pgf/.tikz images [9.3 (9.3-elpaplus @ .emacs.d/elpa/org-plus-contrib-20191203/)]
@ 2019-12-06  6:47  1% Arthur
  0 siblings, 0 replies; 200+ results
From: Arthur @ 2019-12-06  6:47 UTC (permalink / raw)
  To: emacs-orgmode


[-- Attachment #1.1: Type: text/plain, Size: 1531 bytes --]

Remember to cover the basics, that is, what you expected to happen and
what in fact did happen.  You don't know how to make a good report?  See

     https://orgmode.org/manual/Feedback.html#Feedback

Your bug report will be posted to the Org mailing list.
------------------------------------------------------------------------

Hi,

Since my last org update (today or yesterday I would say) I have been
having an issue with exporting .pgf or .tikz file to LaTeX.  The
exporter always returns `nil`.

I attached a patch that can fix this.  It is not thoroughly tested by my
assumption is that the `progn` does not actually "set" variable
`image-code`, hence the `nil`.

Attached:
 - org file to reproduce the error.
 - tex file output by the org exporter.
 - output of `org-submit-bug-report` (it is waaay too long)
 - the patch I wrote which basically removes the `progn` block and
   replaces it by a single `setq`.

In summary, when you have [[file:test.pgf]] and export to LaTeX:
 - Expected output:
   \begin{center}
   \input{test.pgf}
   \end{center}
 - Actual output:
   \begin{center}
   nil
   \end{center

Summary of config:
 - GNU Emacs 25.2.2 (x86_64-pc-linux-gnu, GTK+ Version 3.22.21) of
   2017-09-23, modified by Debian
 - Org mode version 9.3 (9.3-elpaplus @
.emacs.d/elpa/org-plus-contrib-20191203/)

My apologies if this comes from some weird thing in my config,
although I have checked with `emacs -Q -l <base-config>`.  I have
tried with full file, subtree, custom and default LaTeX class.

Regards,
Arthur

[-- Attachment #1.2: Type: text/html, Size: 1848 bytes --]

[-- Attachment #2: ox-latex.patch --]
[-- Type: text/x-patch, Size: 1915 bytes --]

--- org-plus-contrib-20191203/ox-latex.el	2019-12-06 17:28:34.258945803 +1100
+++ org-plus-contrib-20191203/ox-latex.el	2019-12-06 17:28:53.765352128 +1100
@@ -2411,21 +2411,22 @@
 	;; - if options are present, wrap in a tikzpicture environment.
 	;; - if width or height are present, use \resizebox to change
 	;;   the image size.
-	(progn
-	  (setq image-code (format "\\input{%s}" path))
-	  (when (org-string-nw-p options)
-	    (setq image-code
-		  (format "\\begin{tikzpicture}[%s]\n%s\n\\end{tikzpicture}"
-			  options
-			  image-code)))
-	  (setq image-code
-		(cond ((org-string-nw-p scale)
-		       (format "\\scalebox{%s}{%s}" scale image-code))
-		      ((or (org-string-nw-p width) (org-string-nw-p height))
-		       (format "\\resizebox{%s}{%s}{%s}"
-			       (if (org-string-nw-p width) width "!")
-			       (if (org-string-nw-p height) height "!")
-			       image-code)))))
+        (setq image-code
+              (let* ((image-base (format "\\input{%s}" path))
+                     (image-input
+                      (if (org-string-nw-p options)
+                          (format "\\begin{tikzpicture}[%s]\n%s\n\\end{tikzpicture}"
+                                  options
+                                  image-base)
+                        image-base)))
+                (cond ((org-string-nw-p scale)
+                       (format "\\scalebox{%s}{%s}" scale image-input))
+                      ((or (org-string-nw-p width) (org-string-nw-p height))
+                       (format "\\resizebox{%s}{%s}{%s}"
+                               (if (org-string-nw-p width) width "!")
+                               (if (org-string-nw-p height) height "!")
+                               image-input))
+                      (t image-base))))
       ;; For other images:
       ;; - add scale, or width and height to options.
       ;; - include the image with \includegraphics.

[-- Attachment #3: test.tex --]
[-- Type: text/x-tex, Size: 741 bytes --]

% Created 2019-12-06 Fri 17:41
% Intended LaTeX compiler: pdflatex
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{grffile}
\usepackage{longtable}
\usepackage{wrapfig}
\usepackage{rotating}
\usepackage[normalem]{ulem}
\usepackage{amsmath}
\usepackage{textcomp}
\usepackage{amssymb}
\usepackage{capt-of}
\usepackage{hyperref}
\author{soha}
\date{\today}
\title{}
\hypersetup{
 pdfauthor={soha},
 pdftitle={},
 pdfkeywords={},
 pdfsubject={},
 pdfcreator={Emacs 25.2.2 (Org mode 9.3)}, 
 pdflang={English}}
\begin{document}

\tableofcontents


\section{Bug: \LaTeX{} export does not handle .pgf/.tikz images}
\label{sec:org5faca5a}

\begin{center}
nil
\end{center}
\end{document}

[-- Attachment #4: test.org --]
[-- Type: application/octet-stream, Size: 353 bytes --]

#+latex_class: article
#+latex_class_options:
#+latex_header:
#+latex_header_extra:
#+description:
#+keywords:
#+subtitle:
#+latex_compiler: pdflatex
#+date: \today

* Bug: LaTeX export does not handle .pgf/.tikz images

[[file:test.pgf]]

# Expected:
# \begin{center}
# \input{test.pgf}
# \end{center}
#
# Actual:
# \begin{center}
# nil
# \end{center}

[-- Attachment #5: org-submit-bug-report.out --]
[-- Type: application/octet-stream, Size: 172013 bytes --]

Emacs  : GNU Emacs 25.2.2 (x86_64-pc-linux-gnu, GTK+ Version 3.22.21)
 of 2017-09-23, modified by Debian
Package: Org mode version 9.3 (9.3-elpaplus @ /home/student/.emacs.d/elpa/org-plus-contrib-20191203/)

current state:
==============
(setq
 org-src-lang-modes '(("arduino" . arduino) ("redis" . redis) ("php" . php)
		      ("C" . c) ("C++" . c++) ("asymptote" . asy)
		      ("bash" . sh) ("beamer" . latex) ("calc" . fundamental)
		      ("cpp" . c++) ("ditaa" . artist) ("dot" . fundamental)
		      ("elisp" . emacs-lisp) ("ocaml" . tuareg)
		      ("screen" . shell-script) ("shell" . sh)
		      ("sqlite" . sql))
 org-latex-tables-booktabs t
 org-ref-get-pdf-filename-function 'org-ref-get-pdf-filename
 org-footnote-auto-adjust t
 org-tab-first-hook '(org-babel-hide-result-toggle-maybe
		      org-babel-header-arg-expand)
 org-adapt-indentation nil
 org-latex-classes '(("infor"
		      "\\documentclass[]{interact}\n\\usepackage[utf8]{inputenc}\n\n\\usepackage{epstopdf}% To incorporate .eps illustrations using PDFLaTeX, etc.\n\\usepackage[caption=false]{subfig}% Support for small, `sub' figures and tables\n%\\usepackage[nolists,tablesfirst]{endfloat}% To `separate' figures and tables from text if required\n\n%\\usepackage[doublespacing]{setspace}% To produce a `double spaced' document if required\n%\\setlength\\parindent{24pt}% To increase paragraph indentation when line spacing is doubled\n%\\setlength\\bibindent{2em}% To increase hanging indent in bibliography when line spacing is doubled\n\n\\usepackage{natbib}% Citation support using natbib.sty\n\\bibpunct[, ]{(}{)}{;}{a}{}{,}% Citation support using natbib.sty\n\\renewcommand\\bibfont{\\fontsize{10}{12}\\selectfont}% Bibliography support using natbib.sty\n\n\\theoremstyle{plain}% Theorem-like structures provided by amsthm.sty\n\\newtheorem{theorem}{Theorem}[section]\n\\newtheorem{lemma}[theorem]{Lemma}\n\\newtheorem{corollary}[theorem]{Corollary}\n\\newtheorem{proposition}[theorem]{Proposition}\n\n\\theoremstyle{definition}\n\\newtheorem{definition}[theorem]{Definition}\n\\newtheorem{example}[theorem]{Example}\n\n\\theoremstyle{remark}\n\\newtheorem{remark}{Remark}\n\\newtheorem{notation}{Notation}\n\n[NO-DEFAULT-PACKAGES]\n[EXTRA]\n\\usepackage{hyperref}\n\\usepackage{cleveref}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     ("tufte"
		      "\\documentclass[a4paper, nobib]{tufte-handout}\n\\usepackage[style=apa]{biblatex}\n\\renewcommand{\\cite}[2][0pt]{\\unskip \\sidenote{\\fullcite{#2}}}\n\\usepackage{realscripts}\n% \\usepackage{unicode-math}\n% \\setmathfont[Scale=MatchUppercase]{libertinusmath-regular.otf}\n\\setmonofont[Scale=MatchLowercase]{DejaVu Sans Mono}\n\\setmainfont[\n  Ligatures=TeX,\n  Numbers={OldStyle, Proportional},\n  SmallCapsFeatures = {LetterSpace = 5, Renderer = Basic}\n                       % Ligatures={NoCommon, NoRequired, NoContextual}}\n]{Linux Libertine O}\n\\usepackage[multiple]{fnpct}\n\\setfnpct{add-punct-marks=;:}\n\\AdaptNote\\sidenote\\multsidenote\n[NO-DEFAULT-PACKAGES]\n[EXTRA]\n\\usepackage{cleveref}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     ("paper"
		      "\\documentclass[a4paper, 11pt, svgnames]{article}\n[DEFAULT-PACKAGES]\n\\newlength{\\alphabet}\n\\settowidth{\\alphabet}{\\normalfont abcdefghijklmnopqrstuvwxyz}\n\\usepackage[textwidth=2.3\\alphabet]{geometry}\n\\usepackage{amssymb}\n\\usepackage{mathtools}\n\\usepackage{xspace}\n\\usepackage[svgnames]{xcolor}\n\\usepackage{booktabs}\n\\usepackage{multirow}\n\\usepackage{pgfplots} % External TikZ/PGF support (thanks to Andreas Nautsch)\n\\usetikzlibrary{calc,positioning,shapes,arrows,positioning,fit,backgrounds}\n\\usepgfplotslibrary{fillbetween}\n\\usepackage{fontspec}\n\\usepackage{unicode-math}\n\\setmainfont[\n  Ligatures=TeX,\n  Numbers={OldStyle, Proportional},\n  SmallCapsFeatures = {LetterSpace = 5, Renderer = Basic}\n                       % Ligatures={NoCommon, NoRequired, NoContextual}}\n]{Linux Libertine O}\n\\newfontfamily\\headerfont[\n  LetterSpace=5,\n  WordSpace=1.5,\n  Ligatures=NoCommon,\n  Numbers={OldStyle, Proportional},\n  Kerning=Uppercase,\n  Letters=SmallCaps,\n  Numbers={OldStyle, Proportional}\n]{Linux Libertine O}\n\\newfontfamily\\acrofont[\n  LetterSpace=5,\n  WordSpace=1.5,\n  Ligatures=NoCommon,\n  Kerning=Uppercase,\n  Letters={SmallCaps, UppercaseSmallCaps},\n  Numbers={OldStyle, Proportional}\n]{Linux Libertine O}\n\\setmathfont[Scale=MatchUppercase]{libertinusmath-regular.otf}\n\\setmonofont[Scale=MatchLowercase]{DejaVu Sans Mono}\n\\usepackage{etoolbox}\n\\setlength{\\baselineskip}{13pt}\n\\renewcommand{\\arraystretch}{1.2}\n\\newcommand\\lining{\\addfontfeatures{Numbers={Proportional, Lining}}}\n\\newcommand\\fixed{\\addfontfeatures{Numbers={Monospaced, Lining}}}\n\\AtBeginEnvironment{tabular}{\\fixed}\n\\renewcommand{\\theequation}{{\\lining\\arabic{equation}}}\n\\frenchspacing\n\\usepackage{titlesec}\n\\newcommand{\\flatcaps}[1]{{\\headerfont \\MakeLowercase{#1}}}\n\\titleformat{\\section}{\\large\\bfseries}{\\lining\\thesection}{1em}{}\n\\titleformat{\\subsection}{\\large}{\\thesubsection}{.6em}{\\flatcaps}\n\\titleformat{\\subsubsection}{}{\\thesubsubsection}{.6em}{\\itshape}\n\\titleformat{\\paragraph}[runin]{\\headerfont}{\\theparagraph}{0pt}{}[.]\n\\titlespacing*{\\section}{0pt}{2\\baselineskip}{1\\baselineskip}\n\\titlespacing*{\\subsection}{0pt}{1\\baselineskip}{1\\baselineskip}\n\\titlespacing*{\\subsubsection}{0pt}{8pt}{5pt}\n\\usepackage[tracking]{microtype}\n\\usepackage{enumitem}\n\\setlist{noitemsep, nosep, leftmargin=\\parindent}\n\\setlist[1]{labelindent=\\parindent} % < Usually a good idea\n\\setlist[description]{font=\\mdseries\\flatcaps, labelindent=0pt} % Have to remove the bold\n\\usepackage{caption}\n\\usepackage{subcaption}\n\\DeclareCaptionLabelFormat{lc}{\\flatcaps{#1}~{#2}}\n\\captionsetup{font=small, format=plain, labelformat=lc, width=.9\\textwidth}\n\\captionsetup[subfigure]{labelsep=colon, labelfont=sc, labelformat=simple}\n\\usepackage[\n  normal-marks,\n  normal-mark-width=\\parindent,\n  % normal-indent=0em,\n  % normal-par-indent=\\parindent\n]{fnpct}\n\\setfnpct{add-punct-marks=;:}\n\\usepackage{realscripts}\n\\usepackage{selnolig}\n\\usepackage[runin]{abstract}\n\\renewcommand{\\abstractnamefont}{\\normalfont\\flatcaps}\n\\abslabeldelim{\\newline}\n\\setlength{\\abstitleskip}{-\\parindent}\n\\usepackage[\n  natbib=true,\n  style=authoryear,\n  % citestyle=numeric-comp,\n  autocite=inline,\n  maxbibnames=100,\n  mincitenames=1,\n  maxcitenames=2,\n  hyperref=true,\n  % uniquelist=false,\n  % uniquename=init,\n  giveninits=true,\n  dashed=false,\n  useprefix=true,\n  date=year,\n  isbn=false, eprint=true, url=false, % Do not print extra info\n]{biblatex}\n% \\renewcommand*{\\citesetup}{%\n%  \\lining\n%  \\biburlsetup\n%  \\frenchspacing}\n%% Period inside the quotes, please.\n\\uspunctuation\n\\DeclareNameAlias{sortname}{family-given}\n\\renewcommand{\\finentrypunct}{} % Remove period at end of reference\n\\AtBeginBibliography{\\sloppy}\n%% Acronyms\n\\usepackage[printonlyused, smaller]{acronym}\n% \\newcommand\\acrofont\n\\renewcommand*{\\acsfont}[1]{{\\acrofont #1}}\n\\renewcommand*{\\aclabelfont}[1]{{\\acrofont #1}}\n[PACKAGES]\n[EXTRA]\n% Cleveref needs to be last\n\\usepackage{cleveref}\n\\hypersetup{pdftex, breaklinks, colorlinks, urlcolor=FireBrick, linkcolor=NavyBlue, citecolor=ForestGreen}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     ("svmult"
		      "\\documentclass[11pt]{svmult}\n\\usepackage[utf8]{inputenc}\n\\usepackage[T1]{fontenc}\n\\usepackage{fixltx2e}\n\\usepackage{longtable}\n\\usepackage{float}\n\\usepackage{wrapfig}\n\\usepackage{rotating}\n\\usepackage[normalem]{ulem}\n\\usepackage{amsmath}\n\\usepackage{textcomp}\n\\usepackage{marvosym}\n\\usepackage{wasysym}\n\\usepackage{amssymb}\n\\usepackage{hyperref}\n\\usepackage{mathptmx}\n\\usepackage{helvet}\n\\usepackage{courier}\n\\usepackage{type1cm}\n\\usepackage{makeidx}\n\\usepackage{graphicx}\n\\usepackage{multicol}\n\\usepackage[bottom]{footmisc}\n\\providecommand{\\e}[1]{\\ensuremath{\\times 10^{#1}}}\n[NO-DEFAULT-PACKAGES] [PACKAGES] [EXTRA]"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     ("thesis"
		      "\\documentclass[headinclude, footinclude, cleardoublepage=empty,\n                paper=a4, fontsize=11pt, svgnames      % Fix xcolor errors\n]{scrreprt}\n\n\\input{classicthesis-config}\n\\input{macros}\n\\input{tikz}\n\\setcounter{secnumdepth}{2} % <-- 2 numbers up to subsections\n[NO-DEFAULT-PACKAGES]\n[EXTRA]"
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     ("thesis-full"
		      "\\documentclass[twoside, openright, titlepage, numbers=noenddot, %1headlines,\n                headinclude, footinclude, cleardoublepage=empty, abstract=on,\n                BCOR=5mm, paper=a4, fontsize=11pt,\n                svgnames      % Fix xcolor errors\n]{scrreprt}\n\n\\input{classicthesis-config}\n\\input{macros}\n\\input{tikz}\n[NO-DEFAULT-PACKAGES]"
		      ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     ("article" "\\documentclass[11pt]{article}"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     ("report" "\\documentclass[11pt]{report}"
		      ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
		     ("book" "\\documentclass[11pt]{book}"
		      ("\\part{%s}" . "\\part*{%s}")
		      ("\\chapter{%s}" . "\\chapter*{%s}")
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
		     )
 org-speed-command-hook '(org-speed-command-activate
			  org-babel-speed-command-activate)
 org-ref-create-notes-hook '((lambda nil (org-narrow-to-subtree)
			      (insert
			       (format "cite:%s\n"
				(org-entry-get (point) "Custom_ID"))
			       )
			      )
			     )
 org-occur-hook '(org-first-headline-recenter)
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-html-format-drawer-function '(closure
				   (htmlize-buffer-places
				    org-html-format-table-no-css
				    htmlize-css-name-prefix
				    htmlize-output-type htmlize-output-type
				    htmlize-css-name-prefix t)
				   (_name contents) contents)
 org-latex-format-inlinetask-function 'org-latex-format-inlinetask-default-function
 org-confirm-shell-link-function 'yes-or-no-p
 org-ascii-format-inlinetask-function 'org-ascii-format-inlinetask-default
 org-ref-open-pdf-function 'org-ref-open-pdf-at-point
 org-ref-cite-onclick-function 'org-ref-cite-click-helm
 org-latex-pdf-process '("latexmk -gg -shell-escape -interaction=nonstopmode -lualatex %f")
 org-ref-insert-label-function 'org-ref-helm-insert-label-link
 org-latex-format-headline-function 'org-latex-format-headline-default-function
 org-latex-image-default-width ""
 org-latex-format-drawer-function '(closure (t) (_ contents) contents)
 org-odt-format-headline-function 'org-odt-format-headline-default-function
 org-ref-pdf-to-bibtex-function 'copy-file
 org-src-mode-hook '(org-src-babel-configure-edit-buffer
		     org-src-mode-configure-edit-buffer)
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-babel-pre-tangle-hook '(save-buffer)
 org-mode-hook '(org-ref-org-menu
		 (closure
		  (org--rds reftex-docstruct-symbol
		   org-element-greater-elements org-clock-history
		   org-agenda-current-date org-with-time org-defdecode org-def
		   org-read-date-inactive org-ans2 org-ans1
		   org-columns-current-fmt-compiled org-clock-current-task
		   org-clock-effort org-agenda-skip-function
		   org-agenda-skip-comment-trees org-agenda-archives-mode
		   org-end-time-was-given org-time-was-given
		   org-log-note-extra org-log-note-purpose
		   org-log-post-message org-last-inserted-timestamp
		   org-last-changed-timestamp
		   org-entry-property-inherited-from org-blocked-by-checkboxes
		   org-state org-agenda-headline-snapshot-before-repeat
		   org-capture-last-stored-marker org-agenda-start-on-weekday
		   org-agenda-buffer-tmp-name org-priority-regexp
		   buffer-face-mode-face org-tbl-menu org-org-menu
		   org-struct-menu org-entities org-last-state
		   org-id-track-globally org-clock-start-time texmathp-why
		   remember-data-file
		   org-agenda-tags-todo-honor-ignore-options
		   iswitchb-temp-buflist calc-embedded-open-mode
		   calc-embedded-open-formula calc-embedded-close-formula
		   align-mode-rules-list org-emphasis-alist
		   org-emphasis-regexp-components
		   org-export-registered-backends org-modules
		   org-babel-load-languages org-indent-indentation-per-level
		   org-element-paragraph-separate ffap-url-regexp
		   org-inlinetask-min-level t)
		  nil
		  (add-hook (quote change-major-mode-hook)
		   (quote org-show-all) (quote append) (quote local))
		  )
		 (closure
		  (org-src-window-setup *this*
		   org-babel-confirm-evaluate-answer-no
		   org-src-preserve-indentation org-src-lang-modes
		   org-edit-src-content-indentation org-babel-library-of-babel
		   t)
		  nil
		  (add-hook (quote change-major-mode-hook)
		   (quote org-babel-show-result-all) (quote append)
		   (quote local))
		  )
		 org-babel-result-hide-spec org-babel-hide-all-hashes
		 org-eldoc-load org-ref-setup-label-finders)
 org-ref-insert-cite-function 'org-ref-helm-insert-cite-link
 org-latex-prefer-user-labels t
 org-bibtex-headline-format-function '(closure
				       (org-id-locations
					org-agenda-search-view-always-boolean
					org-agenda-overriding-header t)
				       (entry) (cdr (assq :title entry)))
 org-latex-caption-above nil
 org-archive-hook '(org-attach-archive-delete-maybe)
 org-ascii-format-drawer-function '(closure (t) (_name contents _width)
				    contents)
 org-odt-format-inlinetask-function 'org-odt-format-inlinetask-default-function
 org-ref-insert-ref-function 'org-ref-helm-insert-ref-link
 org-cycle-hook '(org-cycle-hide-archived-subtrees org-cycle-show-empty-lines
		  org-optimize-window-after-visibility-change)
 org-ref-bibtex-assoc-pdf-with-entry-move-function 'rename-file
 org-link-shell-confirm-function 'yes-or-no-p
 org-export-async-init-file "~/.emacs.d/tools/async.el"
 org-ref-clean-bibtex-key-function '(lambda (key)
				     (replace-regexp-in-string ":" "" key))
 org-ref-clean-bibtex-entry-hook '(org-ref-bibtex-format-url-if-doi
				   orcb-key-comma org-ref-replace-nonascii
				   orcb-& orcb-% org-ref-title-case-article
				   orcb-clean-year orcb-key orcb-clean-doi
				   orcb-clean-pages orcb-check-journal
				   org-ref-sort-bibtex-entry orcb-fix-spacing)
 org-link-elisp-confirm-function 'yes-or-no-p
 org-babel-tangle-lang-exts '(("python" . "py") ("emacs-lisp" . "el")
			      ("elisp" . "el"))
 org-confirm-elisp-link-function 'yes-or-no-p
 org-export-in-background t
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-odt-format-drawer-function '(closure
				  (hfy-user-sheet-assoc hfy-html-quote-regex
				   hfy-html-quote-map hfy-face-to-css
				   hfy-begin-span-handler hfy-end-span-handler
				   archive-zip-extract
				   nxml-auto-insert-xml-declaration-flag t)
				  (_name contents) contents)
 org-ref-open-notes-function '(lambda nil (org-show-entry)
			       (outline-show-branches) (outline-show-children)
			       (org-cycle (quote (64)))
			       (recenter-top-bottom 0))
 org-html-format-headline-function 'org-html-format-headline-default-function
 org-link-parameters '(("attachment" :follow org-attach-open-link :export
			org-attach-export-link :complete
			org-attach-complete-link)
		       ("id" :follow org-id-open)
		       ("eww" :follow eww :store org-eww-store-link)
		       ("rmail" :follow org-rmail-open :store
			org-rmail-store-link)
		       ("mhe" :follow org-mhe-open :store org-mhe-store-link)
		       ("irc" :follow org-irc-visit :store org-irc-store-link
			:export org-irc-export)
		       ("info" :follow org-info-open :export org-info-export
			:store org-info-store-link)
		       ("gnus" :follow org-gnus-open :store
			org-gnus-store-link)
		       ("docview" :follow org-docview-open :export
			org-docview-export :store org-docview-store-link)
		       ("bbdb" :follow org-bbdb-open :export org-bbdb-export
			:complete org-bbdb-complete-link :store
			org-bbdb-store-link)
		       ("w3m" :store org-w3m-store-link)
		       ("printindex" :follow org-ref-index :export
			(lambda (path desc format)
			 (cond
			  ((eq format (quote latex)) (format "\\printindex")))
			 )
			)
		       ("index" :follow (lambda (path) (occur path)) :export
			(lambda (path desc format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\index{%s}" path))
			  )
			 )
			)
		       ("bibentry" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-bibentry :complete
			org-bibentry-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Autocites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Autocites :complete
			org-Autocites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("autocites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-autocites :complete
			org-autocites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("supercites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-supercites :complete
			org-supercites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Textcites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Textcites :complete
			org-Textcites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("textcites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-textcites :complete
			org-textcites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Smartcites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Smartcites :complete
			org-Smartcites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("smartcites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-smartcites :complete
			org-smartcites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footcitetexts" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-footcitetexts :complete
			org-footcitetexts-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footcites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-footcites :complete
			org-footcites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Parencites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Parencites :complete
			org-Parencites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("parencites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-parencites :complete
			org-parencites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Cites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Cites :complete
			org-Cites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("cites" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-cites :complete
			org-cites-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("fnotecite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-fnotecite :complete
			org-fnotecite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Pnotecite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Pnotecite :complete
			org-Pnotecite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("pnotecite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-pnotecite :complete
			org-pnotecite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Notecite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Notecite :complete
			org-Notecite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("notecite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-notecite :complete
			org-notecite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footfullcite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-footfullcite :complete
			org-footfullcite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("fullcite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-fullcite :complete
			org-fullcite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeurl" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citeurl :complete
			org-citeurl-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citedate*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citedate* :complete
			org-citedate*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citedate" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citedate :complete
			org-citedate-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citetitle*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citetitle* :complete
			org-citetitle*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citetitle" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citetitle :complete
			org-citetitle-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citeauthor*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Citeauthor* :complete
			org-Citeauthor*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Autocite*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Autocite* :complete
			org-Autocite*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("autocite*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-autocite* :complete
			org-autocite*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Autocite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Autocite :complete
			org-Autocite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("autocite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-autocite :complete
			org-autocite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("supercite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-supercite :complete
			org-supercite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("parencite*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-parencite* :complete
			org-parencite*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("cite*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-cite* :complete
			org-cite*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Smartcite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Smartcite :complete
			org-Smartcite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("smartcite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-smartcite :complete
			org-smartcite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Textcite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Textcite :complete
			org-Textcite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("textcite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-textcite :complete
			org-textcite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footcitetext" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-footcitetext :complete
			org-footcitetext-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("footcite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-footcite :complete
			org-footcite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Parencite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Parencite :complete
			org-Parencite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("parencite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-parencite :complete
			org-parencite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Cite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Cite :complete
			org-Cite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citeauthor" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Citeauthor :complete
			org-Citeauthor-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citealp" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Citealp :complete
			org-Citealp-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citealt" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Citealt :complete
			org-Citealt-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citep" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Citep :complete
			org-Citep-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("Citet" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-Citet :complete
			org-Citet-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeyearpar" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citeyearpar :complete
			org-citeyearpar-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeyear*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citeyear* :complete
			org-citeyear*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeyear" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citeyear :complete
			org-citeyear-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeauthor*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citeauthor* :complete
			org-citeauthor*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citeauthor" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citeauthor :complete
			org-citeauthor-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citetext" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citetext :complete
			org-citetext-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citenum" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citenum :complete
			org-citenum-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citealp*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citealp* :complete
			org-citealp*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citealp" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citealp :complete
			org-citealp-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citealt*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citealt* :complete
			org-citealt*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citealt" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citealt :complete
			org-citealt-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citep*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citep* :complete
			org-citep*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citep" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citep :complete
			org-citep-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citet*" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citet* :complete
			org-citet*-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("citet" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-citet :complete
			org-citet-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("nocite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-nocite :complete
			org-nocite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			)
		       ("cite" :follow
			(lambda (_)
			 (funcall org-ref-cite-onclick-function nil))
			:export org-ref-format-cite :complete
			org-cite-complete-link :help-echo
			(lambda (window object position)
			 (when org-ref-show-citation-on-enter
			  (save-excursion (goto-char position)
			   (let
			    ((s
			      (org-ref-format-entry
			       (org-ref-get-bibtex-key-under-cursor))
			      )
			     )
			    (with-temp-buffer (insert s) (fill-paragraph)
			     (buffer-string))
			    )
			   )
			  )
			 )
			:face org-ref-cite-link-face-fn :display full :keymap
			(keymap
			 (tab lambda nil (interactive)
			  (funcall org-ref-insert-cite-function))
			 (S-up . org-ref-sort-citation-link)
			 (S-right lambda nil (interactive)
			  (org-ref-swap-citation-link 1))
			 (S-left lambda nil (interactive)
			  (org-ref-swap-citation-link -1))
			 (C-right . org-ref-next-key)
			 (C-left . org-ref-previous-key)
			 (16777337 lambda nil
			  "Paste key at point. Assumes the first thing in the killring is a key."
			  (interactive)
			  (org-ref-insert-key-at-point (car kill-ring)))
			 (16777303 lambda nil "Copy all the keys at point."
			  (interactive)
			  (kill-new
			   (org-element-property :path (org-element-context)))
			  )
			 (16777335 lambda nil (interactive)
			  (kill-new (car (org-ref-get-bibtex-key-and-file))))
			 (16777318 lambda nil (interactive)
			  (save-excursion (org-ref-open-citation-at-point)
			   (kill-new (org-ref-format-bibtex-entry-at-point)))
			  )
			 (16777319 . org-ref-google-scholar-at-point)
			 (16777317 lambda nil "Email entry at point"
			  (interactive) (org-ref-open-citation-at-point)
			  (org-ref-email-bibtex-entry))
			 (16777315 . org-ref-wos-citing-at-point)
			 (16777330 . org-ref-wos-related-at-point)
			 (16777326 . org-ref-open-notes-at-point)
			 (16777328 . org-ref-open-pdf-at-point)
			 (16777333 . org-ref-open-url-at-point)
			 (16777314 . org-ref-open-citation-at-point)
			 (16777327 . org-ref-cite-hydra/body)
			 (follow-link . mouse-face)
			 (mouse-3 . org-find-file-at-mouse)
			 (mouse-2 . org-open-at-mouse))
			:store org-ref-bibtex-store-link)
		       ("Cref" :follow org-ref-ref-follow :export
			org-ref-Cref-export :complete org-ref-complete-link
			:face org-ref-ref-face-fn :help-echo
			org-ref-ref-help-echo)
		       ("cref" :follow org-ref-ref-follow :export
			org-ref-cref-export :complete org-ref-complete-link
			:face org-ref-ref-face-fn :help-echo
			org-ref-ref-help-echo)
		       ("autoref" :follow org-ref-ref-follow :export
			org-ref-autoref-export :complete org-ref-complete-link
			:face org-ref-ref-face-fn :help-echo
			org-ref-ref-help-echo)
		       ("eqref" :follow org-ref-ref-follow :export
			org-ref-eqref-export :complete org-ref-complete-link
			:face org-ref-ref-face-fn :help-echo
			org-ref-ref-help-echo)
		       ("nameref" :follow org-ref-ref-follow :export
			org-ref-export-nameref :complete org-ref-complete-link
			:face org-ref-ref-face-fn :help-echo
			org-ref-ref-help-echo)
		       ("pageref" :follow org-ref-ref-follow :export
			(lambda (path desc format)
			 (cond
			  ((eq format (quote html))
			   (format "(<pageref>%s</pageref>)" path))
			  ((eq format (quote latex))
			   (format "\\pageref{%s}" path))
			  )
			 )
			:face org-ref-ref-face-fn :complete
			org-pageref-complete-link :help-echo
			org-ref-ref-help-echo)
		       ("ref" :follow org-ref-ref-follow :export
			org-ref-ref-export :complete org-ref-complete-link
			:face org-ref-ref-face-fn :help-echo
			org-ref-ref-help-echo)
		       ("label" :follow
			(lambda (label)
			 "On clicking count the number of label tags used in the buffer.\nA number greater than one means multiple labels!"
			 (let
			  
			  ((count
			    
																	       
			    (org-ref-count-labels label)
			    
			    
																	       
																	       )
																	      
			   )
			  
			  (message
			   
			   (format
			    
																	       
																	       
			    "%s occurence%s"
			    
																	       
																	       
			    count
			    
																	       
																	       
			    (if
			     
																		
																		
																		
																		
																		
																		
																		
																		
																		
																			
																			      
																					       
			     (or
			      
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																			 
																			 
																			 
																			       
																			       
																						
																						
																						       
			      (= count 0)
			      
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																			 
																			 
																			 
																			       
																			       
																						
																						
																						       
			      (> count 1)
			      
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																		 
																			 
																			 
																			 
																			       
																			       
																						
																						
																						       
			      )
			     
			     
			     
																		
																		
																		
																		
																		
																		
																		
																		
																		
																			
																			      
																					       
			     "s" "")
			    
																	       
																	       
			    )
			   
			   (org-ref-count-labels label)
			   
			   )
			  
			  )
			 )
			:export
			(lambda (keyword desc format)
			 (cond
			  ((eq format (quote html))
			   (format "<div id=\"%s\"></div>" keyword))
			  ((eq format (quote md))
			   (format "<a name=\"%s\"></a>" keyword))
			  ((eq format (quote latex))
			   (format "\\label{%s}" keyword))
			  )
			 )
			:store org-label-store-link :face
			org-ref-label-face-fn :help-echo
			(lambda (window object position)
			 (save-excursion (goto-char position)
			  (let ((s (org-ref-link-message)))
			   (let
			    ((temp-buffer (generate-new-buffer " *temp*")))
			    (save-current-buffer (set-buffer temp-buffer)
			     (unwind-protect
			      (progn (insert s) (fill-paragraph)
			       (buffer-string))
			      (and (buffer-name temp-buffer)
			       (kill-buffer temp-buffer))
			      )
			     )
			    )
			   )
			  )
			 )
			)
		       ("list-of-tables" :follow org-ref-list-of-tables
			:export
			(lambda (keyword desc format)
			 (cond
			  ((eq format (quote latex)) (format "\\listoftables"))
			  )
			 )
			)
		       ("list-of-figures" :follow org-ref-list-of-figures
			:export
			(lambda (keyword desc format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\listoffigures"))
			  )
			 )
			)
		       ("addbibresource" :follow org-ref-follow-addbibresource
			:export
			(lambda (keyword desc format)
			 (cond ((eq format (quote html)) (format ""))
			  ((eq format (quote latex))
			   (format "\\addbibresource{%s}" keyword))
			  )
			 )
			)
		       ("bibliographystyle" :export
			(lambda (keyword desc format)
			 (cond
			  ((or (eq format (quote latex))
			    (eq format (quote beamer)))
			   (format "\\bibliographystyle{%s}" keyword))
			  (t ""))
			 )
			)
		       ("printbibliography" :follow org-ref-open-bibliography
			:export
			(lambda (keyword desc format)
			 (cond
			  ((eq format (quote org))
			   (org-ref-get-org-bibliography))
			  ((eq format (quote html))
			   (org-ref-get-html-bibliography))
			  ((eq format (quote latex))
			   org-ref-printbibliography-cmd)
			  )
			 )
			)
		       ("nobibliography" :follow org-ref-open-bibliography
			:export org-ref-nobibliography-format)
		       ("bibliography" :follow org-ref-open-bibliography
			:export org-ref-bibliography-format :complete
			org-bibliography-complete-link :help-echo
			(lambda (window object position)
			 (save-excursion (goto-char position)
			  (let ((s (org-ref-link-message)))
			   (let
			    ((temp-buffer (generate-new-buffer " *temp*")))
			    (save-current-buffer (set-buffer temp-buffer)
			     (unwind-protect
			      (progn (insert s) (fill-paragraph)
			       (buffer-string))
			      (and (buffer-name temp-buffer)
			       (kill-buffer temp-buffer))
			      )
			     )
			    )
			   )
			  )
			 )
			:face org-ref-bibliography-face-fn)
		       ("Acp" :follow or-follow-acronym :face
			org-ref-acronym-face :help-echo or-acronym-tooltip
			:export
			(closure
			 ((mapping "Acp" . "Glspl") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" (cdr mapping) path))
			  (t (format "%s" (upcase path))))
			 )
			)
		       ("acp" :follow or-follow-acronym :face
			org-ref-acronym-face :help-echo or-acronym-tooltip
			:export
			(closure
			 ((mapping "acp" . "glspl") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" (cdr mapping) path))
			  (t (format "%s" (upcase path))))
			 )
			)
		       ("Ac" :follow or-follow-acronym :face
			org-ref-acronym-face :help-echo or-acronym-tooltip
			:export
			(closure ((mapping "Ac" . "Gls") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" (cdr mapping) path))
			  (t (format "%s" (upcase path))))
			 )
			)
		       ("ac" :follow or-follow-acronym :face
			org-ref-acronym-face :help-echo or-acronym-tooltip
			:export
			(closure ((mapping "ac" . "gls") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" (cdr mapping) path))
			  (t (format "%s" (upcase path))))
			 )
			)
		       ("acrfull" :follow or-follow-acronym :face
			org-ref-acronym-face :help-echo or-acronym-tooltip
			:export
			(closure
			 ((mapping "acrfull" . "acrfull") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" (cdr mapping) path))
			  (t (format "%s" (upcase path))))
			 )
			)
		       ("acrlong" :follow or-follow-acronym :face
			org-ref-acronym-face :help-echo or-acronym-tooltip
			:export
			(closure
			 ((mapping "acrlong" . "acrlong") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" (cdr mapping) path))
			  (t (format "%s" (upcase path))))
			 )
			)
		       ("acrshort" :follow or-follow-acronym :face
			org-ref-acronym-face :help-echo or-acronym-tooltip
			:export
			(closure
			 ((mapping "acrshort" . "acrshort") (--dolist-tail--)
			  t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" (cdr mapping) path))
			  (t (format "%s" (upcase path))))
			 )
			)
		       ("glslink" :follow or-follow-glossary :face
			org-ref-glossary-face :help-echo or-glossary-tooltip
			:export
			(closure (t) (path desc format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\glslink{%s}{%s}" path desc))
			  (t (format "%s" path)))
			 )
			)
		       ("glsdesc" :follow or-follow-glossary :face
			org-ref-glossary-face :help-echo or-glossary-tooltip
			:export
			(closure ((command . "glsdesc") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" command path))
			  (t (format "%s" path)))
			 )
			)
		       ("glssymbol" :follow or-follow-glossary :face
			org-ref-glossary-face :help-echo or-glossary-tooltip
			:export
			(closure ((command . "glssymbol") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" command path))
			  (t (format "%s" path)))
			 )
			)
		       ("Glspl" :follow or-follow-glossary :face
			org-ref-glossary-face :help-echo or-glossary-tooltip
			:export
			(closure ((command . "Glspl") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" command path))
			  (t (format "%s" path)))
			 )
			)
		       ("Gls" :follow or-follow-glossary :face
			org-ref-glossary-face :help-echo or-glossary-tooltip
			:export
			(closure ((command . "Gls") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" command path))
			  (t (format "%s" path)))
			 )
			)
		       ("glspl" :follow or-follow-glossary :face
			org-ref-glossary-face :help-echo or-glossary-tooltip
			:export
			(closure ((command . "glspl") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" command path))
			  (t (format "%s" path)))
			 )
			)
		       ("gls" :follow or-follow-glossary :face
			org-ref-glossary-face :help-echo or-glossary-tooltip
			:export
			(closure ((command . "gls") (--dolist-tail--) t)
			 (path _ format)
			 (cond
			  ((eq format (quote latex))
			   (format "\\%s{%s}" command path))
			  (t (format "%s" path)))
			 )
			)
		       ("bibtex" :follow org-bibtex-open :store
			org-bibtex-store-link)
		       ("file+sys") ("file+emacs")
		       ("shell" :follow org-link--open-shell)
		       ("news" :follow
			(closure
			 ((scheme . "news") (--dolist-tail--) org-ts-regexp
			  org-time-stamp-formats org-src-source-file-name
			  org-outline-regexp-bol org-inhibit-startup
			  org-id-link-to-org-use-id org-highlight-links
			  org-comment-string org-agenda-buffer-name
			  clean-buffer-list-kill-buffer-names t)
			 (url) (browse-url (concat scheme ":" url)))
			)
		       ("mailto" :follow
			(closure
			 ((scheme . "mailto") (--dolist-tail--) org-ts-regexp
			  org-time-stamp-formats org-src-source-file-name
			  org-outline-regexp-bol org-inhibit-startup
			  org-id-link-to-org-use-id org-highlight-links
			  org-comment-string org-agenda-buffer-name
			  clean-buffer-list-kill-buffer-names t)
			 (url) (browse-url (concat scheme ":" url)))
			)
		       ("https" :follow
			(closure
			 ((scheme . "https") (--dolist-tail--) org-ts-regexp
			  org-time-stamp-formats org-src-source-file-name
			  org-outline-regexp-bol org-inhibit-startup
			  org-id-link-to-org-use-id org-highlight-links
			  org-comment-string org-agenda-buffer-name
			  clean-buffer-list-kill-buffer-names t)
			 (url) (browse-url (concat scheme ":" url)))
			)
		       ("http" :follow
			(closure
			 ((scheme . "http") (--dolist-tail--) org-ts-regexp
			  org-time-stamp-formats org-src-source-file-name
			  org-outline-regexp-bol org-inhibit-startup
			  org-id-link-to-org-use-id org-highlight-links
			  org-comment-string org-agenda-buffer-name
			  clean-buffer-list-kill-buffer-names t)
			 (url) (browse-url (concat scheme ":" url)))
			)
		       ("ftp" :follow
			(closure
			 ((scheme . "ftp") (--dolist-tail--) org-ts-regexp
			  org-time-stamp-formats org-src-source-file-name
			  org-outline-regexp-bol org-inhibit-startup
			  org-id-link-to-org-use-id org-highlight-links
			  org-comment-string org-agenda-buffer-name
			  clean-buffer-list-kill-buffer-names t)
			 (url) (browse-url (concat scheme ":" url)))
			)
		       ("help" :follow org-link--open-help)
		       ("file" :complete org-link-complete-file)
		       ("elisp" :follow org-link--open-elisp)
		       ("doi" :follow doi-link-menu :export
			(lambda (doi desc format)
			 (cond
			  ((eq format (quote html))
			   (format "<a href=\"%s%s\">%s</a>"
			    doi-utils-dx-doi-org-url doi
			    (or desc (concat "doi:" doi)))
			   )
			  ((eq format (quote latex))
			   (format "\\href{%s%s}{%s}" doi-utils-dx-doi-org-url
			    doi (or desc (concat "doi:" doi)))
			   )
			  )
			 )
			)
		       )
 org-structure-template-alist '(("n" . "notes") ("a" . "export ascii")
				("c" . "center") ("C" . "comment")
				("e" . "example") ("E" . "export")
				("h" . "export html") ("l" . "export latex")
				("q" . "quote") ("s" . "src") ("v" . "verse"))
 org-babel-load-languages '((emacs-lisp . t) (python . t))
 org-ref-insert-link-function 'org-ref-helm-insert-cite-link
 org-html-format-inlinetask-function 'org-html-format-inlinetask-default-function
 org-ref-notes-function 'org-ref-notes-function-one-file
 org-clock-out-hook '(org-clock-remove-empty-clock-drawer)
 org-confirm-babel-evaluate nil
 org-publish-project-alist '(("thesis" :base-directory "~/writing/thesis"
			      :publishing-directory "~/writing/thesis/pdf"
			      :publishing-function org-latex-publish-to-pdf
			      :base-extension "org" :with-title nil :with-toc
			      nil)
			     ("talks" :base-directory "~/presentations/org/"
			      :publishing-directory "~/presentations/html/"
			      :publishing-function
			      org-reveal-publish-to-reveal :base-extension
			      "org" :with-title t :with-toc nil :recursive t)
			     ("talks-static" :base-directory
			      "~/presentations/org/" :base-extension
			      "css\\|js\\|png\\|jpe?g\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|svg" :publishing-directory "~/presentations/html/" :recursive t :publishing-function org-publish-attachment)
			     )
 )

^ permalink raw reply	[relevance 1%]

* Re: [bug] Export to latex truncates long subsections (WE attached)
  2019-08-27  7:42  7%     ` Julius Dittmar
@ 2019-08-27  8:10  0%       ` Tim Cross
  0 siblings, 0 replies; 200+ results
From: Tim Cross @ 2019-08-27  8:10 UTC (permalink / raw)
  To: emacs-orgmode


I think I agree with Julius. While it may be a legitimate use case, the
risk that it will break other use cases seems a bit high (I've never run
into this issue in many years of org use).

Perhaps add another document 'type' into 'org-latex-classes which adds
the xpatch and associated change to the default. I have a number of such
'templates' (e.g. to generate work documents with the 'approved' colours
and logo etc). It works quite well.

Tim


Julius Dittmar <Julius.Dittmar@gmx.de> writes:

> Hi folks,
>
> Am 27.08.19 um 08:57 schrieb Vladimir Nikishkin:
>> I have indeed investigated the issue, and this is the link:
>> https://latex.org/forum/viewtopic.php?f=47&t=32788
>>
>> To make the long story short, the folowing trick is needed to allow
>> page breaks after headings (which is a completely standard case in
>> -org).
>>
>> #+begin_src latex
>> \usepackage{xpatch}
>> \makeatletter
>> % This is not recommended, because it can break several things
>> \xpatchcmd{\@afterheading}{\@nobreaktrue}{\@nobreakfalse}{%
>> \typeout{WARNING: \string\@afterheading\space broken}%
>> }{%
>> \@latexerr{ERROR: Cannot patch \string\@afterheading}\@ehd%
>> }
>> \makeatother
>> #+end_src
>>
>> Shall this trick be considered for inclusion in 'org' officially?
>> I mean, having lists of empty headings is a perfectly standard use case for org.
>
> I would not want that as the default. Yes, it is one standard use case.
> It would break other standard use cases, like creating ordinary
> documents, though.
>
> Perhaps variant adding such a patch could be added to org-latex-classes,
> or at least mentioned in the docs to org-latex-classes? That way you can
> use this "class" version for such cases without adding unnecessary
> uglyness to other org-created documents.
>
> Another possible approach would be a change in the export functions.
> What really is needed here, from my point of view, is that the export
> adds a superficial paragraph to a heading in the case that there's no
> content at all. Nothing should be added if the heading has sub-headings,
> I count that as content. In case there is no content at all, then some
> form of breakable vertical space should be added. I don't know enough
> LaTeX to find the least intrusive way, though I'd try \vspace{0pt}.
>
> I did never dig into the export functions, so I don't know how difficult
> that would be.
>
> Just my thoughts,
> Julius Dittmar


--
Tim Cross

^ permalink raw reply	[relevance 0%]

* Re: [bug] Export to latex truncates long subsections (WE attached)
  @ 2019-08-27  7:42  7%     ` Julius Dittmar
  2019-08-27  8:10  0%       ` Tim Cross
  0 siblings, 1 reply; 200+ results
From: Julius Dittmar @ 2019-08-27  7:42 UTC (permalink / raw)
  To: emacs-orgmode

Hi folks,

Am 27.08.19 um 08:57 schrieb Vladimir Nikishkin:
> I have indeed investigated the issue, and this is the link:
> https://latex.org/forum/viewtopic.php?f=47&t=32788
>
> To make the long story short, the folowing trick is needed to allow
> page breaks after headings (which is a completely standard case in
> -org).
>
> #+begin_src latex
> \usepackage{xpatch}
> \makeatletter
> % This is not recommended, because it can break several things
> \xpatchcmd{\@afterheading}{\@nobreaktrue}{\@nobreakfalse}{%
> \typeout{WARNING: \string\@afterheading\space broken}%
> }{%
> \@latexerr{ERROR: Cannot patch \string\@afterheading}\@ehd%
> }
> \makeatother
> #+end_src
>
> Shall this trick be considered for inclusion in 'org' officially?
> I mean, having lists of empty headings is a perfectly standard use case for org.

I would not want that as the default. Yes, it is one standard use case.
It would break other standard use cases, like creating ordinary
documents, though.

Perhaps variant adding such a patch could be added to org-latex-classes,
or at least mentioned in the docs to org-latex-classes? That way you can
use this "class" version for such cases without adding unnecessary
uglyness to other org-created documents.

Another possible approach would be a change in the export functions.
What really is needed here, from my point of view, is that the export
adds a superficial paragraph to a heading in the case that there's no
content at all. Nothing should be added if the heading has sub-headings,
I count that as content. In case there is no content at all, then some
form of breakable vertical space should be added. I don't know enough
LaTeX to find the least intrusive way, though I'd try \vspace{0pt}.

I did never dig into the export functions, so I don't know how difficult
that would be.

Just my thoughts,
Julius Dittmar

^ permalink raw reply	[relevance 7%]

* Re: from org to openoffice presentations (or make org looks like openoffice)
  2019-07-25  7:53  7%       ` Luca Ferrari
@ 2019-07-25  9:16  0%         ` Fraga, Eric
  0 siblings, 0 replies; 200+ results
From: Fraga, Eric @ 2019-07-25  9:16 UTC (permalink / raw)
  To: Luca Ferrari; +Cc: emacs-org list

On Thursday, 25 Jul 2019 at 09:53, Luca Ferrari wrote:
> Thanks a lot, I'm refactoring it to my needs but it is a very good
> starting point. However, I had to place a
> \usepackage{tikz}
> in the theme file to make it compile.

Yes, indeed; I have that as a default package to load by org for all
LaTeX export cases as I use tikz all the time.

> Now, the first question is: is there a way I define the image width to
> automatically adjust to the slide size?
> Something like the following almost work:
>
> \node[inner sep=0pt,above,left] (logo) at (\paperwidth,8pt)
> {\includegraphics[width=\paperwidth]{images/logo.png}};
>
> but the image does not keep proportions. It would be better to enlarge
> the image from right to left up to all the space before the page
> numbering. Any hint?

Nothing beyond what you have already done.  I am surprised that the
image proportions are not preserved.  Maybe post a minimal example
(including an image)?

-- 
: Professor Eric S Fraga, http://www.homepages.ucl.ac.uk/~ucecesf
: Required hieroglyphics follow: ∀ε>0,∃δ>0∋|x-x₀|<δ⇒|f(x)-f(x₀)|<ε
: PGP/GPG key: 8F5C 279D 3907 E14A 5C29  570D C891 93D8 FFFC F67D

^ permalink raw reply	[relevance 0%]

* Re: from org to openoffice presentations (or make org looks like openoffice)
  2019-07-24 12:12  6%     ` Fraga, Eric
@ 2019-07-25  7:53  7%       ` Luca Ferrari
  2019-07-25  9:16  0%         ` Fraga, Eric
  0 siblings, 1 reply; 200+ results
From: Luca Ferrari @ 2019-07-25  7:53 UTC (permalink / raw)
  To: Fraga, Eric; +Cc: emacs-org list

On Wed, Jul 24, 2019 at 2:12 PM Fraga, Eric <e.fraga@ucl.ac.uk> wrote:
> I've attached three files: an org file, the resulting PDF, and a very
> minimal beamer theme that may be of use.  That theme puts an image (UCL
> logo) at the bottom right of the slide and a page number at the bottom
> left side.  Maybe you can modify this to your satisfaction.  Note the
> naming of the beamer theme file and how you refer to it in the org file.

Thanks a lot, I'm refactoring it to my needs but it is a very good
starting point. However, I had to place a
\usepackage{tikz}
in the theme file to make it compile.

Now, the first question is: is there a way I define the image width to
automatically adjust to the slide size?
Something like the following almost work:

\node[inner sep=0pt,above,left] (logo) at (\paperwidth,8pt)
{\includegraphics[width=\paperwidth]{images/logo.png}};

but the image does not keep proportions. It would be better to enlarge
the image from right to left up to all the space before the page
numbering. Any hint?

Thanks,
Luca

^ permalink raw reply	[relevance 7%]

* Re: from org to openoffice presentations (or make org looks like openoffice)
  @ 2019-07-24 12:12  6%     ` Fraga, Eric
  2019-07-25  7:53  7%       ` Luca Ferrari
  0 siblings, 1 reply; 200+ results
From: Fraga, Eric @ 2019-07-24 12:12 UTC (permalink / raw)
  To: Luca Ferrari; +Cc: emacs-org list

[-- Attachment #1: Type: text/plain, Size: 1594 bytes --]

On Wednesday, 24 Jul 2019 at 13:42, Luca Ferrari wrote:
> Yes, this is what I'm doing so far. The problems I see are:
> 1) the image contains a footer, and LaTeX does not anything about such
> footer so sometimes text can overlap with the footer. If I isolate the
> footer as a separate image, how can I specify to place it to the
> bottom of each slide and have beamer not placing controls and other
> text on the slides?

As soon as you want this type of control, you'll end up having to design
your own beamer theme.  There are many themes out there: I suggest you
have a look at which one(s) come(s) close to what you want, copy it, and
change it accordingly.  But this will require a certain level of
LaTeX-fu unfortunately.

I've attached three files: an org file, the resulting PDF, and a very
minimal beamer theme that may be of use.  That theme puts an image (UCL
logo) at the bottom right of the slide and a page number at the bottom
left side.  Maybe you can modify this to your satisfaction.  Note the
naming of the beamer theme file and how you refer to it in the org file.

> 2) I usually provide two sets of slides, one dark and one light

Two themes...?

> By the way, things were even worst of how I described them: the
> template was Microsoft Office (not even Open Office)!

For me, they are equivalent in any case: I do not like word processors
as they make me do the job of a typesetter and I'd rather worry about
content.  But I know what you mean.

Best of luck,
eric

-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.2.4-399-g4e6222

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: t.org --]
[-- Type: text/x-org; name="t.org", Size: 180 bytes --]

#+beamer_theme: minimal
#+title: The title
#+author: ESF
#+options: toc:nil

* This is a test
1. first point
2. second point
* Second slide
- third point
- fourth point

[-- Attachment #3: t.pdf --]
[-- Type: application/pdf, Size: 46645 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: beamerthememinimal.sty --]
[-- Type: text/x-tex; name="beamerthememinimal.sty", Size: 1722 bytes --]

\ProvidesPackage{beamerthememinimal}[2017/04/28 Inspired by a presentation from Rio Tinto]
\usepackage{lastpage}
\mode<presentation>
%\newcommand{\versioninformation}{}

\definecolor{maincolour}{HTML}{00A400}  % darkgreen
\definecolor{modelinecolour}{HTML}{483D8B} % dark slate blue
\definecolor{modelinebgcolour}{HTML}{104E8B} % dodger blue 4
% background
\setbeamertemplate{background}{
  \begin{tikzpicture}
  \useasboundingbox (0,0) rectangle(\the\paperwidth,\the\paperheight);
   \node[inner sep=0pt,above,left] (ucllogo) at (\paperwidth,8pt) {\includegraphics[height=10pt]{ucl-white-transparent}};
  \ifnum\thepage>1\relax%
  \node[above,right] (pagenumber) at (0,1.2ex) {{\tiny\color{lightgray} \thepage/\pageref{LastPage}
      ~\insertsectionhead
      \ifdef{\versioninformation}{~\color{gray}\versioninformation}{}}};
  \fi
  \end{tikzpicture}
}

% colours
\setbeamercolor{structure}{fg=maincolour}
%\setbeamercolor{block title alerted}{fg=maincolour}
\setbeamercolor{background canvas}{bg=black,fg=white} 
\usebeamercolor[fg]{background canvas}
\setbeamercolor{block title}{fg=maincolour}
\setbeamercolor{block body}{fg=white}
\setbeamercolor{frametitle}{fg=white}
\setbeamercolor{item}{fg=maincolour}
\setbeamercolor*{normal text}{fg=white,bg=black}
\setbeamercolor*{alerted text}{fg=maincolour}
\setbeamercolor{section in toc}{fg=maincolour}
\setbeamercolor{subsection in toc}{fg=maincolour}
\setbeamercolor*{title}{fg=white}
\setbeamercolor*{title page header}{fg=white}
% fonts
\setbeamerfont{frametitle}{series=\bfseries}
\setbeamerfont{title}{size=\Large,series=\bfseries}

\setbeamertemplate{items}[ball]
\setbeamertemplate{navigation symbols}{}

\mode <all>

^ permalink raw reply	[relevance 6%]

* Definitive answer to org-mode export HTML versus LaTeX
@ 2019-01-29 16:06 10% Lawrence Bottorff
  0 siblings, 0 replies; 200+ results
From: Lawrence Bottorff @ 2019-01-29 16:06 UTC (permalink / raw)
  To: emacs-orgmode Mailinglist

[-- Attachment #1: Type: text/plain, Size: 2787 bytes --]

I keep being stymied by the apparent incompatibility of HTML and LaTeX
export. Here's what I have in my .org file header:

#+LATEX_CLASS: article
#+LATEX_CLASS_OPTIONS: [american]
#+LATEX_HEADER: \usepackage{tikz}
#+LATEX_HEADER: \usepackage{commath}
#+LATEX_HEADER: \usepackage{stackengine}
#+LaTeX_HEADER: \usepackage{pgfplots}
#+LaTeX_HEADER: \usepackage{sansmath}
#+LATEX_HEADER: \usepackage{mathtools}
#+LaTeX_HEADER: \usepackage{amsmath}

In reality, I don't know if this gets seen by org-mode export to HTML,
perhaps by export to LaTeX? So to start, here is working piece of markup
that displays great in both HTML and LaTeX:

#+begin_src latex :packages '(("" "tikz")) :exports results :results output
raw :file other12.png :imagemagick yes :iminoptions -density 600
:imoutoptions -geometry 500

\usetikzlibrary{decorations.pathreplacing}

  \begin{tikzpicture}[scale=1]
    \draw[step=1cm,thin,gray!60] (-6,-6) grid (6,6);
    \draw[<->] (-6,0)--(6,0) node[right]{$x$};
    \draw[<->] (0,-6)--(0,6) node[above]{$y$};
    \draw[line width=2pt,blue,-stealth](0,0)--(4,-3) node[anchor=south
west]{$\boldsymbol{(4,-3)}$};
    \draw[line width=2pt,gray,-stealth](2,3)--(6,0) node[anchor=south west];
    \draw[line width=2pt,gray,-stealth](-5,4)--(-1,1) node[anchor=south
west];
    \draw[line width=2pt,gray,-stealth](-3,-1)--(1,-4) node[anchor=south
west];
\draw
[decorate,color=red,decoration={brace,amplitude=10pt},xshift=-0pt,yshift=0pt]
(-5.0,1.0) -- (-5.0,4.0) node [red,midway,xshift=-0.65cm]
{\footnotesize $-3$};
    \draw
[decorate,color=red,decoration={brace,amplitude=10pt,mirror,raise=1pt},xshift=-0pt,yshift=0pt]
(-5,1) -- (-1,1) node [red,midway,yshift=-0.6cm] {\footnotesize $4$};
  \end{tikzpicture}

#+end_src

The following also displays in both HTML and LaTeX correctly:

\begin{align*}
\|x\|&=\sqrt{4^2+(-3)^2} \\
&= \sqrt{25} \\
&= 5
\end{align*}
as well as this:

\begin{equation*}
    x = \begin{pmatrix}
        \phantom{-} 4 \\
           -3 \\
        \end{pmatrix}
 \end{equation*}

but this on the HTML side

\setstackEOL{\\}
\begin{equation*}
x=\parenVectorstack[r]{4\\-3\\2}
\end{equation*}

doesn't know what \setstackEOL{\\} is, nor \parenVectorstack[r] and
displays mangled. The LaTeX export looks fine, though. And if I put it in a
LaTeX babel code block, it disappears from the HTML entirely, while, again,
the LaTeX export displays just fine. Confusing is how the Tikz code block
is displayed in both HTML and LaTeX, but any other attempt at a LaTeX code
block is ignored and left completely out of the HTML export.

My educated guess is that the org-mode HTML export processes is handled by
MathJax, which is a subset of LaTeX. But then I'd like to know definitively
what can be done and what cannot be done LaTeX-wise for the HTML export.

LB

[-- Attachment #2: Type: text/html, Size: 3598 bytes --]

^ permalink raw reply	[relevance 10%]

* getting close on latex letterheads [was: letterhead and signature in odt export]
  @ 2018-11-01 12:47  4%               ` Matt Price
  0 siblings, 0 replies; 200+ results
From: Matt Price @ 2018-11-01 12:47 UTC (permalink / raw)
  To: ckelty ckelty; +Cc: Org Mode

[-- Attachment #1: Type: text/plain, Size: 5686 bytes --]

OK, so I'm getting close to being able to do this. My almost-working
example doc is at the bottom of this email, I have a question about
suppressing the headline text.

On Tue, Oct 30, 2018 at 11:50 PM ckelty ckelty <ckelty@gmail.com> wrote:

> Matt,
>
>
> > On Oct 30, 2018, at 6:26 PM, Matt Price <moptop99@gmail.com> wrote:
> >
> > Hi again Chris!
> >
> > OK, so I understand a little bit of this. I would like to keep all my
> letters in subheadings in a single org doc, and just export once. This
> version requires a fair amount of latex in every subtree.
>
> Unless I am misunderstanding, you should be able to restrict what you
> export to your subtree with a C-s (C-c C-e C-s l o) and just have one file
> with the Latex Headers at the top… or you can do what Tim suggested and put
> it in org-latex-classes variable (but I don’t know how to do that).
>
> I think I may actually understand this now.  See my example below, which
almost works.

>
> >
> > Also... where should I go to learn more about latex (I have
> beengoogling, I've found some places, am wondering what the *best* place
> is)? It appears I am approaching adulthood and am ready to learn how to use
> it, after years of resisting :-/
> >
>
> Ahhh… that way lies madness.  Welcome.  I would learn as little LaTeX as
> necessary and allow org to do the rest.  ShareLatex, Overleaf, and
> StackExchange are all fine starting points
>
> I'm definitely learning something, though yes, I feel a bit like the Mad
Hatter.

So I am pretty close.  As you suggested, turns out I can put almost all the
latex in the document header.  The only thing that still needs to go into
the letter body is the \mysig command that I have defined in the header.

This works fine if I have no headlines in the letter text, but if I try to
export a subtree, then I guess the headline gets read as a title, and
either org or latex inserts it immediately after my custom \maketitle
command.

It seems to me then that I either have to always set the export_title
property of subheadings to the empty string; add a temporary filter to
ox-latex; or just write my own derived backend that does al lthis work for
me, and maybe add a keybinding for that to make it easier to access (my
export dispatcher is getting pretty crowded...).  Setting #+OPTIONS:
title:nil does not seem ot have any effect :-(

Still, maybe some of y'all have ideas on how to improve what I've already
got, which is below. Thanks again!

#+STARTUP: indent
#+LANGUAGE: en
#+OPTIONS: num:nil  toc:nil ':t
#+AUTHOR
#+EMAIL: Your Email Here
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
#+LATEX_HEADER: \usepackage[T1]{fontenc}
#+LATEX_HEADER: \usepackage{graphicx}
#+LATEX_HEADER: \usepackage{float}
#+LATEX_HEADER: \usepackage{wrapfig}
#+LATEX_HEADER: \usepackage{rotating}
#+LATEX_HEADER: \usepackage[normalem]{ulem}
#+LATEX_HEADER: \usepackage{hyperref}
#+LATEX_HEADER: \usepackage{setspace}
#+LATEX_HEADER: \usepackage{libertine}
#+LATEX_HEADER: \usepackage[left=1.0in,right=1.0in]{geometry}
#+LATEX_HEADER: \setlength{\parskip}{1em}
#+LATEX_HEADER: \setlength{\parindent}{0pt}
#+LATEX_HEADER:
\newenvironment{temphelvet}{\fontfamily{phv}\selectfont}{\par}
#+LATEX_HEADER: \makeatletter
#+LATEX_HEADER: \def\@maketitle{
#+LATEX_HEADER: \begin{minipage}{0.14\textwidth}
#+LATEX_HEADER:
\includegraphics[width=1.8cm]{./Pictures/1000020100000107000001CF636AB597708AB63A.png}
#+LATEX_HEADER: \end{minipage}
#+LATEX_HEADER: \begin{minipage}{0.86\textwidth}
#+LATEX_HEADER: \begin{temphelvet}
#+LATEX_HEADER: {\huge University of Toronto}
#+LATEX_HEADER: \vspace{-2pt}
#+LATEX_HEADER: \hrule
#+LATEX_HEADER: \vspace{3pt}
#+LATEX_HEADER: \textbf{\textsc{dept. of history}}  \newline
#+LATEX_HEADER: {\small \textsc{ Rm. 2074 sidney smith, 100 st. george
street}, TORONTO, ONTARIO  M5S 3G3  CANADA \newline
#+LATEX_HEADER: \textsc{Telephone 416-978-3363    Fax 416-978-4810} }
#+LATEX_HEADER: \end{temphelvet}
#+LATEX_HEADER: \end{minipage}
#+LATEX_HEADER: \hfill}
#+LATEX_HEADER: \makeatother
#+LATEX_HEADER: \newcommand{\mysig}{
#+LATEX_HEADER: Please do not hesitate to contact me with any questions or
concerns.\\
#+LATEX_HEADER: Sincerely,\\
#+LATEX_HEADER: \fromsig{\includegraphics[scale=1]{my-sig.png}} \\
#+LATEX_HEADER: \fromname{Matt Price}
#+LATEX_HEADER: }
#

#+LATEX_HEADER_EXTRA:  \maketitle
# #+LATEX_HEADER_EXTRA: \onehalfspacing


* Frankie
I had the pleasure of teaching Frankie Goes To Hollywood in my 4th year
seminar in Spring of 1987. Frankie stood out then as now as one of the
loudest students I had ever encountered. At the same time, Frankie's work
forced me to confront my own inability to *relax*. After years of
psychotherapy, I now believe that that seminar was one of the best parts of
my life.  All the "trauma" Frankie caused me turn out to have been
excellent learning experiences.

It is thus with great pleasure that my therapist, I mean I, recommend
Frankie for your stupid fellowship.

\mysig

* Joey
Joey Ramone was a student in my class "School's out for Summer" at /Rock
and Roll High School/ some time in the late 1970's, I can't remember the
year exactly. Since the students burned the school down, and left me
without a job, I really can't see why the would have asked me for a letter
of reference, but I'm so alone and desolate that I agreed to write him one.
However, I really don't have a single good thing to say about him.  I know
you're not reading these letters anyway, though, so I suppose I can say
whatever I want here. That Long Island school board still owes me money!

\mysig

[-- Attachment #2: Type: text/html, Size: 6569 bytes --]

^ permalink raw reply	[relevance 4%]

* Re: letterhead and signature in odt export
  2018-10-31  1:26  0%           ` Matt Price
  2018-10-31  1:30  6%             ` Matt Price
  @ 2018-10-31 14:53  0%             ` John Kitchin
  2 siblings, 0 replies; 200+ results
From: John Kitchin @ 2018-10-31 14:53 UTC (permalink / raw)
  To: Matt Price; +Cc: jrfilipovits, Org Mode, ckelty

I went down the path of a custom latex style, with custom exporter some
years ago. At the time, I was head of our undergrad committee, and I had
to write a lot of memo style documents on department letterhead. This
setup allowed me to quickly write memos and export them to pdfs. I also
use this for other things like letters of recommendation these days. I
put each one in a separate file.

I defined this skeleton (which you run by typing M-x memo) that makes it
easy to get a memo started:

(define-skeleton memo
  "CMU memo template"
  nil
  "#+LATEX_CLASS: cmu-memo
#+CC:
#+DEPARTMENT: Department of Chemical Engineering
#+FROM: John Kitchin
#+FROMNAME: John Kitchin
#+SIGNATURE-LINES: nil
#+SUBJECT: "_"
#+TO: "@"
#+latex_header: \\usepackage{setspace}
#+latex_header: \\doublespacing

Sincerely,\\\\
\\\\
\\\\
\\\\
John Kitchin

* build :noexport:
[[elisp:(cmu-memo-export-to-pdf-and-open)]]
")

Other solutions include a yasnippet, tempo, ...

I wrote an exporter you can find at
https://github.com/jkitchin/scimax/blob/master/ox-cmu/ox-cmu-memo.el
that uses the keywords to fill in parts of the document template.
Finally, I adapted
http://pi.math.cornell.edu/ADMIN/Computers/latex-letterhead/culetter.sty
to put all the header/logo info in and made it into a latex package. The
main reason for this is that the logo file is in the package, so I don't
have to know its path, worry about moving it, etc.

Knowing what I know now, and now my needs are a little simpler, I guess
you could avoid the sty file and achieve this via the exporter. It
mostly depends on where you want the information to get from org to
latex. Since I have some information in org-format, the exporter is
needed I think.

Regarding where to learn LaTeX, https://en.wikibooks.org/wiki/LaTeX
seems pretty good, but probably it won't help you understand that sty
file! That is written in tex.

There are many ways to get something suitable, I hope this helps!





Matt Price <moptop99@gmail.com> writes:

> Hi again Chris!
>
> OK, so I understand a little bit of this. I would like to keep all my
> letters in subheadings in a single org doc, and just export once. This
> version requires a fair amount of latex in every subtree. It would be nicer
> if the exporter just took care of the latex for me and I didn't have to
> look at it while I'm composing (I know that's not an issue for you,
> Chris).
>
> Is my best option to create an export-derived-backend based on latex (I see
> that's what John K has done in scimax)? Or is the preferred method to
> create a new latex class (whatever that is -- really I have no idea) and
> add the header and closing lines to that?
>
> Also... where should I go to learn more about latex (I have beengoogling,
> I've found some places, am wondering what the *best* place is)? It appears
> I am approaching adulthood and am ready to learn how to use it, after years
> of resisting :-/
>
> m
>
> On Tue, Oct 30, 2018 at 11:56 AM ckelty ckelty <ckelty@gmail.com> wrote:
>
>> I don’t mess around with LibreOffice, but if you want to do it in Org,
>> this is what I do and it works fine. Some of the preamble is superfluous—
>> for various letters I’ve had to add other LaTeX packages….
>>
>> ck
>>
>>
>> >
>> >
>> >
>>
>> #+STARTUP: indent
>> #+LANGUAGE: en
>> #+OPTIONS: num:nil  toc:nil ':t
>> #+AUTHOR: Your Name Here
>> #+EMAIL: Your Email Here
>> #+LATEX_HEADER: \usepackage[utf8]{inputenc}
>> #+LATEX_HEADER: \usepackage[T1]{fontenc}
>> #+LATEX_HEADER: \usepackage{graphicx}
>> #+LATEX_HEADER: \usepackage{float}
>> #+LATEX_HEADER: \usepackage{wrapfig}
>> #+LATEX_HEADER: \usepackage{rotating}
>> #+LATEX_HEADER: \usepackage[normalem]{ulem}
>> #+LATEX_HEADER: \usepackage{hyperref}
>> #+LATEX_HEADER: \usepackage{setspace}
>> #+LATEX_HEADER: \usepackage{libertine}
>> #+LATEX_HEADER: \usepackage[left=1.5in,right=1.5in]{geometry}
>> #+LATEX_HEADER: \setlength{\parskip}{1em}
>> #+LATEX_HEADER: \setlength{\parindent}{0pt}
>>
>> # Insert your graphic here-- getting the scale right can take some work
>> \includegraphics[scale=0.145]{Your LetterHead PNG/JPG}
>>
>> \hfill \today
>>
>> [ Greeting Here ]
>>
>> # I use setspace and onehalfspacing to control line spacing
>> \onehalfspacing
>>
>> [ Insert Inflated Rhetoric About Here ]
>>
>> Yours sincerely,\\
>>
>> # Insert your sig here... ditto on scale.
>> \includegraphics[scale=0.4]{Your Sig PNG/JPG}
>>
>> \textbf{Your Name}\\
>> Illustrious Title\\
>> Second Illustrious Title\\
>> Etc.\\
>>
>>
>> <
>> <
>> <
>>
>> > On Oct 30, 2018, at 7:29 AM, Jeff Filipovits <jrfilipovits@gmail.com>
>> wrote:
>> >
>> > Would you mind sharing them? This is a problem I am trying to figure out
>> as well.
>> >
>> > On Tue, Oct 30, 2018, 9:29 AM Eric S Fraga <esflists@gmail.com> wrote:
>> > Matt,
>> >
>> > I've replied directly to you with some files.
>> > --
>> > Eric S Fraga via Emacs 27.0.50, Org release_9.1.13-783-g97fac4
>> >
>>
>>


--
Professor John Kitchin
Doherty Hall A207F
Department of Chemical Engineering
Carnegie Mellon University
Pittsburgh, PA 15213
412-268-7803
@johnkitchin
http://kitchingroup.cheme.cmu.edu

^ permalink raw reply	[relevance 0%]

* Re: Help with sharing emacs-org presentation
  @ 2018-10-31  7:21  3%       ` Eric S Fraga
  0 siblings, 0 replies; 200+ results
From: Eric S Fraga @ 2018-10-31  7:21 UTC (permalink / raw)
  To: Julius Dittmar; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1627 bytes --]

On Tuesday, 30 Oct 2018 at 20:43, Julius Dittmar wrote:
> Am 30.10.18 um 20:01 schrieb Martin Schöön:
>> My own mantra for preparing slide-packs is to minimize text. I want
>> the audience to listen to me rather than reading text on my slides.
>> My 2 cents...
>
> please don't overdo that.
>
> People have quite different ways of taking in information. Some memorize
> best if they hear something. Others memorize best if they have visual
> input. Others memorize best if they somehow take that information into
> their hands (for example by writing).
>
> If all you give is auditory input, you will leave a lot of interested
> persons in your auditory in the cold.

There is always a balance to be achieved, in my experience.  The trick
is to have slides that support you but do not compete.  If there is too
much text, the audience will be tempted to read and will not be paying
attention to what you say.  I tend towards Martin's view with little or
no text on many slides but slides with text will be limited to 3-4
bullet points and each bullet point having 5-6 words maximum.  But, of
course, this all depends on your intended audience.

In any case, in the spirit of this thread, please find attached a
presentation (both PDF and original org file) I gave earlier this year
to an academic audience consisting mostly of mathematicians and
numerical analysts.  The topic was literate programming but it was
really about org and Emacs.  Lot of interest from the audience and I
hope I converted some to this eco-system.

-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.1.13-783-g97fac4

[-- Attachment #2: talk.pdf --]
[-- Type: application/pdf, Size: 637187 bytes --]

[-- Attachment #3: talk.org --]
[-- Type: text/x-org, Size: 19535 bytes --]

#+title: Literate programming and reproducible research
#+author: Professor Eric S Fraga, UCL
#+macro: lastchange 2018.06.06 10:36

* Introduction

** The aim & challenge

*** Reproducible research

To ensure that our research is *reproducible* both by ourselves and by others.

*** Coding, processing, writing

In doing research,

1. we all *write* programs ...
2. which generate *results* ...
3. which need to be *processed* ...
4. and which should be *disseminated*.

Currently, we use different tools for each step.
*** Tools

Workflow:

- coding :: IDE, MATLAB editor, ~vi~, ~notepad~, ...
- results :: ~.txt~, ~.xls~, ~.dat~
- processing :: spreadsheet, ~R~
- dissemination :: ~Word~, ~PowerPoint~, LaTeX, ~beamer~
- project management :: ?

leading to constant *transfer* of data from one place to another.
** Literate programming

*** Definition

#+begin_quote
Literate programming is a programming paradigm introduced by Donald Knuth in which a program is given as an explanation of the program logic in a natural language, such as English, interspersed with snippets of macros and traditional source code, from which a compilable source code can be generated.
#+end_quote

https://en.wikipedia.org/wiki/Literate_programming

*** Code and documentation

#+attr_latex: :width 0.8\textwidth
[[file:literate-programming-tangling.png]]

[[http://howardism.org/Technical/Emacs/literate-programming-tutorial.html][Source]]
*** Example: the Strawberry algorithm

[[file:strawberry-outline-withborder.png]]

[[https://www.ucl.ac.uk/~ucecesf/strawberry.html]]
** Emacs

*** Editor

- originally written in 1976
- content aware editing
- fully extensible in ~Emacs LISP~
- self-documenting with comprehensive help system
- large eco-system of packages

https://www.gnu.org/software/emacs/
*** org mode

Text (*it's all text*) based mode for

- writing & dissemination
- project management
- literate programming

https://orgmode.org/
* org mode
** Programming
*** Example objective function

\begin{align*}
\min_x z &= \sum_{i=1}^{n} x_i^4 + x_i^3 - 2x_i^2 \\
x & \in [a,b]\cap\mathbb{R}^n
\end{align*}

*** Plot of objective function 

#+results: plot-f
[[file:f.png]]

:plotcode:
#+name: plot-f
#+header: :term "png crop"
#+begin_src gnuplot :file f.png :exports results
  reset
  set cntrparam levels 40 bspline
  set contour base
  set hidden3d
  unset key
  set view 60,326
  set xrange [-2:2]
  set yrange [-2:2]
  unset xtics 
  unset ytics 
  unset ztics 
  unset zlabel
  splot x**4+y**4+x**3+y**3-2*x*x-2*y*y
#+end_src
:end:

*** Tangling

Create an ~octave~ file with the objective function using *tangling*:

#+name: octave-f
#+begin_src octave :tangle "f.m"
  function [z g] = f(x)
    z = sum(x.^4 + x.^3 - 2*x.^2);
    g = 0;  % unconstrained
  endfunction
#+end_src
*** Code segments

Specify the parameters for the optimisation problem:

#+name: problem-setup
#+begin_src octave :noweb yes
  n = 2;
  x0 = rand(n,1);
  a = -2*ones(n,1);
  b = 2*ones(n,1);
#+end_src

*** Bringing bits together

The code to include the problem setup directly and solve the problem:

#+name: strawberry
#+begin_src octave :results value :noweb yes
  clear
  format short
  <<problem-setup>>
  [x y] = strawberry(x0, a, b, @f, 10, 10);
  [x;y]'
#+end_src

:results:
#+name: strawberry-results
#+results: strawberry
|  -1.42716504443494 | -1.443856778049211 |  -5.66531336687728 | 0 |
|  -1.42716504443494 | -1.443856778049211 |  -5.66531336687728 | 0 |
| -1.342508585413797 |  -1.55250372785845 | -5.529004698055015 | 0 |
| -1.360506726205515 | -1.372263538977069 | -5.598345289891352 | 0 |
| -1.468158011926931 | -1.544415421188739 | -5.594381839388814 | 0 |
| -1.339213003233875 |  -1.36422094977677 | -5.569697214609254 | 0 |
| -1.364417892433951 | -1.491553912171922 | -5.615971023198005 | 0 |
| -1.463919469920687 | -1.450505968993437 | -5.663754045524612 | 0 |
| -1.445565121464613 | -1.420730525034394 | -5.663799364174422 | 0 |
| -1.525782025485549 |   -1.5303639151147 | -5.571556830521184 | 0 |
|  -1.40352725450047 | -1.472972377299925 | -5.651863813417487 | 0 |
| -1.410286649811288 | -1.414343225362287 | -5.655462642214252 | 0 |
|  -1.52277571384937 | -1.446360898144175 |  -5.62508035617786 | 0 |
| -1.584751338098946 | -1.373116848847318 | -5.500483131429339 | 0 |
| -1.243018966119808 | -1.476516324299424 | -5.449770831917819 | 0 |
| -1.444138322679675 | -1.666222711962772 | -5.304110381262799 | 0 |
| -1.370072015649149 | -1.525937116930233 | -5.590709124514991 | 0 |
| -1.576526755720007 | -1.530518104917815 | -5.494784345778852 | 0 |
| -1.507786501304049 |  -1.37902437675949 | -5.615657626549971 | 0 |
| -1.450567499881924 | -1.408583920258332 | -5.659381058555995 | 0 |
| -1.535526266987041 | -1.456193641066952 | -5.609133134458752 | 0 |
| -1.238285464782562 |  -1.25198387068423 | -5.254687157245281 | 0 |
| -1.321030271837289 | -1.420499018517368 | -5.580507706519432 | 0 |
| -1.457276546364113 | -1.510431969520121 | -5.636060671059006 | 0 |
| -1.386994515876665 | -1.452244319822924 | -5.647806776697823 | 0 |
| -1.455869791504375 | -1.446387391362544 | -5.665742757998999 | 0 |
|  -1.62382235873763 | -1.442265536388754 | -5.436001199588198 | 0 |
| -1.455447362960834 | -1.404854864255555 | -5.657173423616351 | 0 |
| -1.352852883884089 | -1.468988859997606 | -5.615930658043434 | 0 |
| -1.316282451554356 | -1.481169331825285 | -5.568062394335248 | 0 |
| -1.346872171742821 | -1.559721739239854 |  -5.52227606914515 | 0 |
| -1.392193082324921 | -1.540475777984804 | -5.588469535120524 | 0 |
| -1.358676764875123 | -1.533272203185758 | -5.572011634831901 | 0 |
| -1.430102855019641 | -1.499714214014829 | -5.645120932555698 | 0 |
| -1.375336252513826 | -1.351372446488072 | -5.591923631732472 | 0 |
| -1.323532458220509 | -1.344166563266232 | -5.531090335022149 | 0 |
| -1.493260210372538 | -1.448067147541937 | -5.650501934854817 | 0 |
| -1.497055854832323 | -1.437039672362705 | -5.647851947473225 | 0 |
:end:
*** Plotting results

Using data in table of results on previous slide:

#+results: plot-results
[[file:results.png]]

:plotcode:
#+name: plot-results
#+header: :term "png size 600,600 crop"
#+begin_src gnuplot :var data=strawberry-results :file results.png
  reset
  set contour base
  set cntrparam levels 40
  set xrange [-2:2]
  set yrange [-2:2]
  unset key
  unset xtics
  unset xlabel
  unset ytics
  unset xlabel
  set view 0,0
  splot data using 1:2:3 with points pt 6 ps 1, x**4+y**4+x**3+y**3-2*x*x-2*y*y
#+end_src
:end:

*** Processing results

Statistical analysis of results obtained above:

| Statistic          |  Value |
|--------------------+--------|
| Best               | -5.666 |
| Average            | -5.582 |
| Worst              | -5.255 |
| Standard deviation |  0.094 |
#+TBLFM: @2$2=vmin(remote(strawberry-results,@<$>>..@>$>>));f3::@3$2=vsum(remote(strawberry-results,@<$>>..@>$>>))/vcount(remote(strawberry-results,@<$>>..@>$>>));f3::@4$2=vmax(remote(strawberry-results,@<$>>..@>$>>));f3::@5$2=vsdev(remote(strawberry-results,@<$>>..@>$>>));f3
** Writing
*** Outlines

Example (a recent paper):

[[file:impact-paper-outline.png]]

Can show, hide, and move individual sub-trees.
*** COMMENT Content

- export can handle mathematics:

  \[ y = \sqrt{x} \]

- figures:

  [[file:~/s/personal/avatar-australia-hat-sunglasses-64x64.png]]

- tables (as we have already seen) but with formatting:

  | Item | Description |
  | <l>  |         <r> |
  |------+-------------|
  | One  | Interesting |
  | Two  |      Boring |
*** COMMENT Inline LaTeX for full control

- We can include inline LaTeX directives.
- For instance, \fbox{in a box} would output as you expect.
*** Publishable output

~org~ will *export* to LaTeX (and hence to ~PDF~) or ~ODT~ (~MS Word~ compatible).


[[file:odt-export.png]]
*** Project management
Support for tasks, scheduling, appointments:
**** TODO [3/4] prepare and give presentation on literate programming
DEADLINE: <2018-06-06 Wed>
- [X] collect images
- [X] write slides
- [X] book hotel
- [ ] give presentation
*** Revision control

- A research project is a long term activity comprised of many individual tasks.
- Revision control should (*must*) be an integral element of project management.
- Think *track changes* but on steroids and which works for *data* as well.
- Excellent tools exist: ~git~, ~mercurial~, ~subversion~, ...
*** Example of revision control

[[file:hg-log-view.png]]

* Conclusions

** Summary
*** Emacs & org

Single tool for *writing*, *coding*, *data manipulation*, *data provenance*, *dissemination*, and *project management*.

*** Testimonial I

#+begin_quote
By the age of 35 you should have realized that Emacs is the One True Editor and should have embraced it. If that’s not the case - your life so far has been completely wasted.
#+end_quote

[[https://twitter.com/bbatsov/status/998217369204948992][@bbatsov,  04:02 pm May 20, 2018]]

*** Testimonial II

#+begin_quote
The advantages of plain text are hard to overstate, as is the advantage of having everything from plot notes to research material in a single (large) file under version control. And building up a novel from an outline is a natural process with org-mode.
#+end_quote

Bob Newell, =emacs.help= newsgroup, 2018-05-30.
*** Links

- Emacs :: https://www.gnu.org/software/emacs/
- Complete computing environment :: http://doc.rix.si/cce/cce.html
- org mode :: https://orgmode.org/
- reproducible research :: https://reproducibleresearch.net/links/
- blog :: [[https://dfeich.github.io/www/org-mode/emacs/reproducible-research/2018/05/20/reproducible-research-for-management.html][reproducible research for management]]
*** And finally

[[file:real_programmers.png]]

https://www.xkcd.com/378/

** COMMENT Revision log
#+begin_example

  $Revision: 1.33 $

  $Log: talk.org,v $
  Revision 1.33  2018/06/04 08:14:55  ucecesf
  Summary: reformatted (unfilled) second testimonial

  Revision 1.32  2018/06/04 08:09:32  ucecesf
  Summary: added another Emacs link

  Revision 1.31  2018/05/30 17:09:48  ucecesf
  Summary: added another testimonial

  Revision 1.30  2018/05/28 16:08:22  ucecesf
  Summary: some blank lines added for clearer slides

  Revision 1.29  2018/05/26 09:46:24  ucecesf
  Summary: more commentary and changed order of last two slides

  Revision 1.28  2018/05/25 06:51:00  ucecesf
  Summary: added slide on project management and one on links for further information

  Revision 1.27  2018/05/22 09:15:09  ucecesf
  Summary: added xkcd real programmers use Emacs slide

  Revision 1.26  2018/05/22 06:12:37  ucecesf
  Summary: updated objective function example with subscripts

  Revision 1.25  2018/05/21 19:04:07  ucecesf
  Summary: minor reformatting and added link to Strawberry

  Revision 1.24  2018/05/21 18:58:01  ucecesf
  Summary: added mercurial example

  Revision 1.23  2018/05/21 18:52:08  ucecesf
  Summary: added testimonial on Emacs from twitter

  Revision 1.22  2018/05/21 16:28:25  ucecesf
  Summary: added some commentary and removed superfluous screenshots

  Revision 1.21  2018/05/21 16:14:49  ucecesf
  Summary: added aim and LP figure from web

  Revision 1.20  2018/05/20 14:01:41  ucecesf
  Summary: updated the objective function to be more mathematically precise

  Revision 1.19  2018/05/20 12:40:57  ucecesf
  Summary: added ODT export image and reformatted conclusions

  Revision 1.18  2018/05/20 12:32:19  ucecesf
  Summary: minor formatting to make PDF export look good

  Revision 1.17  2018/05/20 12:23:46  ucecesf
  Summary: added impact paper outline as example

  Revision 1.16  2018/05/20 12:09:36  ucecesf
  Summary: added project management to summary

  Revision 1.15  2018/05/20 12:06:29  ucecesf
  Summary: moved plot of results and hid code

  Also ensured that LaTeX fragments were displayed and text was scaled
  appropriately.

  Revision 1.14  2018/05/20 11:52:33  ucecesf
  Summary: added plot of objective function and show results with contours

  Revision 1.13  2018/05/18 22:45:25  ucecesf
  Summary: added plotting of results slide

  Revision 1.12  2018/05/18 17:46:33  ucecesf
  Summary: added Strawberry folded example

  For literate programming and for outlines in org.

  Revision 1.11  2018/05/18 17:38:10  ucecesf
  Summary: made literate programming slide top level

  Revision 1.10  2018/05/18 17:37:16  ucecesf
  Summary: customised page up/down for slide transitions

  Revision 1.9  2018/05/18 17:04:19  ucecesf
  Summary: added revision log

  Revision 1.8  2018/05/18 17:00:28  ucecesf
  Summary: added conclusions

  revision 1.7 2018/05/18 16:57:44 ucecesf
  Summary: added motivation section

  revision 1.6 2018/05/18 08:03:39 ucecesf
  Summary: settings for beamer export

  revision 1.5 2018/05/17 17:44:07 ucecesf
  Summary: started talking about writing

  revision 1.4 2018/05/17 17:31:35 ucecesf
  Summary: turn off beacon mode to avoid annoying 

  revision 1.3 2018/05/17 17:28:12 ucecesf
  Summary: introduce noweb for code segments

  revision 1.2 2018/05/16 19:30:09 ucecesf
  Summary: added some octave code and tables

  revision 1.1 2018/05/16 16:41:50 ucecesf
  Initial revision

#+end_example
* settings                                                    :noexport:
** org
#+PROPERTY: cache yes
*** beamer settings
#+startup: beamer
Change this setting depending on whether there are sections for the talk or not, with 2 for sections, 1 for no sections and 3 for subsections as well.
#+options: H:3
The theme can be ~minimal~, ~progressbar~, or anything else.
#+beamer_theme: minimal
If links are used directly, colour them gray.
#+latex_header: \hypersetup{colorlinks=true,urlcolor=gray}
#+macro: actualdate 6 June 2018
#+macro: where EGL2018, Essex
#+institute: University College London
# +LATEX_HEADER: \institute{University College London (UCL)}
*** date formatting with version information           :ignoreheading:
**** COMMENT git
#+NAME: mydateline
#+BEGIN_SRC emacs-lisp
(format "#+DATE: \\copyright{} %s\n" *this*) 
#+END_SRC

src_shell[:post mydateline() :results raw]{echo -n $(date +%Y) '@@latex:\\ \vspace*{0.1cm} \tiny \color{gray}@@' version $(git log --format=format:"%ad %h" --date=short | head -1 )} 
**** COMMENT mercurial
#+NAME: mydateline
#+BEGIN_SRC emacs-lisp
(format "#+DATE: \\copyright{} %s\n" *this*) 
#+END_SRC

src_shell[:post mydateline() :results raw]{echo -n $(date +%Y) '@@latex:\\ \vspace*{0.1cm} \tiny \color{gray}@@' version $(hg log slides.org | head -1 | sed -e 's/^.* \([0-9]*\):.*$/\1/')} 
**** rcs
#+latex_header: \usepackage{rcs}
#+latex_header: \RCS $Revision: 1.33 $
#+latex_header: \RCS $Date: 2018/06/04 08:14:55 $
#+date: @@latex:\ifdef{\institute}{@@ {{{actualdate}}} @@latex:\\@@ {{{where}}} @@latex:\\ \vfill\hfill{\tiny\color{gray}v\RCSRevision~\RCSDate}}{@@ @@latex:}@@

*** macros
**** calc: short better formatted version of calculate macro
If the second argument is not given, no variable is stored or shown in the output.

#+macro: calc src_emacs-lisp[:results latex]{(esf/calc-and-output "$1" "$2")}

The macro relies on the following code:

#+name: calc-and-output
#+begin_src emacs-lisp :results silent :exports none
  (defun esf/calc-and-output (expression variable)
    (let ((result (string-to-number (calc-eval (format "evalv(%s)" expression)))))
      (message "Expression %s results in %s" expression result)
      (if (string= "" variable)
          (format "%s = \\fbox{%s}" expression result)
        (progn
          (eval (format "(setq var-%s %s)" variable result))
          (format "\\texttt{%s} \\(\\gets\\) %s = \\fbox{%s}" variable expression result))
        )
      ))
#+end_src 

**** calculate: use emacs calc to evaluate expressions and assign variables
# use listings to export the code evaluated
#+latex_header: \lstdefinelanguage{calc}{}
# evaluate the code and format the output
#+macro: calculate $2 \(\gets\) src_calc[:exports code]{$1} = @@latex:\fbox{@@ src_emacs-lisp{(setq var-$2 (string-to-number (calc-eval "evalv($1)")))} @@latex:}@@
**** cite: macro for citing work and url to actual source
# +macro: cite @@latex:\vfill\Citation{$1}@@@@html:<p style="text-align: right; color: gray;">@@[[$2][$1]]@@html:</p>@@
# alternative cite macro for LaTeX only but with working link
#+macro: cite [[$2][@@latex:\vfill\Citation{$1}@@]]
#+latex_header: \newcommand{\Citation}[1]{\hfill{\scriptsize{\color{gray}#1}}}

**** overlay: for absolute positioning of images etc.
#+latex_header: \usepackage[overlay]{textpos} \TPGrid[0pt,0pt]{20}{20}
#+macro: overlay @@latex:\begin{textblock}{$4}($2,$3)@@[[file:$1]]@@latex:\end{textblock}@@

*** org startup on file visit
#+name: startup
#+begin_src emacs-lisp :results none
  (defun esf/next-slide-or-page-up ()
    (interactive)
    (if (and (boundp 'org-tree-slide-mode) org-tree-slide-mode)
        (org-tree-slide-move-next-tree)
      (scroll-up-command)))
  (local-set-key (kbd "<next>") 'esf/next-slide-or-page-up)

  (defun esf/previous-slide-or-page-down ()
    (interactive)
    (if (and (boundp 'org-tree-slide-mode) org-tree-slide-mode)
        (org-tree-slide-move-previous-tree)
      (scroll-down-command)))
  (local-set-key (kbd "<prior>") 'esf/previous-slide-or-page-down)

  (add-hook 'org-tree-slide-play-hook
            #'(lambda ()
                (setq display-line-numbers nil)
                (beacon-mode -1)
                (setq evil-normal-state-cursor 'bar)
                ;; (evil-emacs-state)
                (hl-line-mode 0)
                (text-scale-set 2)
                (org-toggle-latex-fragment)
                (org-toggle-inline-images)))
  (add-hook 'org-tree-slide-stop-hook
            #'(lambda ()
                (setq display-line-numbers 'visual)
                (beacon-mode 1)
                ;; (evil-normal-state)
                (setq evil-normal-state-cursor 'box)
                (hl-line-mode 1)
                (text-scale-set 0)
                (org-toggle-latex-fragment)
                (org-toggle-inline-images)))
  (org-content 2)
  (setq-local org-confirm-babel-evaluate nil)
  (setq-local org-export-allow-bind-keywords t)
  (setq-local org-fontify-quote-and-verse-blocks t)
  (setq-local org-format-latex-options '(:background default :foreground default :scale 4))
  (setq-local org-latex-image-default-height "5cm")
  (setq-local org-latex-image-default-width nil)
  (setq-local org-latex-pdf-process '("pdflatex -interaction nonstopmode %f"))
  (setq-local org-tree-slide-breadcrumbs " ‣ ")
  ;; (setq-local org-tree-slide-cursor-init nil)
  (setq-local org-tree-slide-fold-subtrees-skipped nil)
  (setq-local org-tree-slide-skip-outline-level 4)
  ;; (setq-local sentence-highlight-mode nil)
  (setq-local time-stamp-line-limit 1000)
  (setq-local time-stamp-format "%04y.%02m.%02d %02H:%02M")
  (setq-local time-stamp-active t)
  (setq-local time-stamp-start "#\\+macro:[ \t]* lastchange[ \t]* ")
  (setq-local time-stamp-end "$")
#+end_src

** local variables
# Local Variables:
# org-confirm-babel-evaluate: nil
# eval: (esf/execute-startup-block)
# End:

^ permalink raw reply	[relevance 3%]

* Re: letterhead and signature in odt export
  2018-10-31  1:26  0%           ` Matt Price
@ 2018-10-31  1:30  6%             ` Matt Price
    2018-10-31 14:53  0%             ` letterhead and signature in odt export John Kitchin
  2 siblings, 0 replies; 200+ results
From: Matt Price @ 2018-10-31  1:30 UTC (permalink / raw)
  To: ckelty, Org Mode

[-- Attachment #1: Type: text/plain, Size: 2196 bytes --]

Oh shoot, I meant to include my sort-of working org text. Not sending the
image file, so you will I guess need to supply your own image in the
corner  -- oh, and also the signature file! - but this is what I have. It
sorta works OK and looks at least a little bit like the History Department
letterhead. Which, I realize, is just a bunch of words written i nHelvetica
with a picture of a beaver next to it.

#+STARTUP: indent
#+LANGUAGE: en
#+OPTIONS: num:nil  toc:nil ':t
#+AUTHOR: Matt Price
#+EMAIL: Your Email Here
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
#+LATEX_HEADER: \usepackage[T1]{fontenc}
#+LATEX_HEADER: \usepackage{graphicx}
#+LATEX_HEADER: \usepackage{float}
#+LATEX_HEADER: \usepackage{wrapfig}
#+LATEX_HEADER: \usepackage{rotating}
#+LATEX_HEADER: \usepackage[normalem]{ulem}
#+LATEX_HEADER: \usepackage{hyperref}
#+LATEX_HEADER: \usepackage{setspace}
#+LATEX_HEADER: \usepackage{libertine}
#+LATEX_HEADER: \usepackage[left=1.0in,right=1.0in]{geometry}
#+LATEX_HEADER: \setlength{\parskip}{1em}
#+LATEX_HEADER: \setlength{\parindent}{0pt}
#+LATEX_HEADER:
\newenvironment{temphelvet}{\fontfamily{phv}\selectfont}{\par}

# Insert your graphic here-- getting the scale right can take some work
\begin{minipage}{0.14\textwidth}
\includegraphics[width=1.8cm]{./Pictures/1000020100000107000001CF636AB597708AB63A.png}
\end{minipage}
\begin{minipage}{0.86\textwidth}
\begin{temphelvet}
{\huge University of Toronto}
\vspace{-2pt}
\hrule
\vspace{3pt}
\textbf{\textsc{dept. of history}}  \newline
{\small \textsc{ Rm. 2074 sidney smith, 100 st. george street}, TORONTO,
ONTARIO  M5S 3G3  CANADA \newline
\textsc{Telephone 416-978-3363    Fax 416-978-4810} }
\end{temphelvet}
\end{minipage}
\hfill \today

[ Greeting Here ]

# I use setspace and onehalfspacing to control line spacing
\onehalfspacing

[ Insert Inflated Rhetoric About Here ]

Yours sincerely,\\

# Insert your sig here... ditto on scale.
\includegraphics[scale=1.0]{/home/matt/Pictures/my-sig-black.png}

\textbf{Your Name}\\
Illustrious Title\\
Second Illustrious Title\\
Etc.\\

* build :noexport:
  :PROPERTIES:
  :CUSTOM_ID: build
  :END:
  #+begin_src emacs-lisp
  (find-file (org-latex-export-to-pdf))
  #+end_src

[-- Attachment #2: Type: text/html, Size: 2505 bytes --]

^ permalink raw reply	[relevance 6%]

* Re: letterhead and signature in odt export
  2018-10-30 15:56  7%         ` ckelty ckelty
@ 2018-10-31  1:26  0%           ` Matt Price
  2018-10-31  1:30  6%             ` Matt Price
                               ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Matt Price @ 2018-10-31  1:26 UTC (permalink / raw)
  To: ckelty; +Cc: jrfilipovits, Org Mode

[-- Attachment #1: Type: text/plain, Size: 2913 bytes --]

Hi again Chris!

OK, so I understand a little bit of this. I would like to keep all my
letters in subheadings in a single org doc, and just export once. This
version requires a fair amount of latex in every subtree. It would be nicer
if the exporter just took care of the latex for me and I didn't have to
look at it while I'm composing (I know that's not an issue for you,
Chris).

Is my best option to create an export-derived-backend based on latex (I see
that's what John K has done in scimax)? Or is the preferred method to
create a new latex class (whatever that is -- really I have no idea) and
add the header and closing lines to that?

Also... where should I go to learn more about latex (I have beengoogling,
I've found some places, am wondering what the *best* place is)? It appears
I am approaching adulthood and am ready to learn how to use it, after years
of resisting :-/

m

On Tue, Oct 30, 2018 at 11:56 AM ckelty ckelty <ckelty@gmail.com> wrote:

> I don’t mess around with LibreOffice, but if you want to do it in Org,
> this is what I do and it works fine. Some of the preamble is superfluous—
> for various letters I’ve had to add other LaTeX packages….
>
> ck
>
>
> >
> >
> >
>
> #+STARTUP: indent
> #+LANGUAGE: en
> #+OPTIONS: num:nil  toc:nil ':t
> #+AUTHOR: Your Name Here
> #+EMAIL: Your Email Here
> #+LATEX_HEADER: \usepackage[utf8]{inputenc}
> #+LATEX_HEADER: \usepackage[T1]{fontenc}
> #+LATEX_HEADER: \usepackage{graphicx}
> #+LATEX_HEADER: \usepackage{float}
> #+LATEX_HEADER: \usepackage{wrapfig}
> #+LATEX_HEADER: \usepackage{rotating}
> #+LATEX_HEADER: \usepackage[normalem]{ulem}
> #+LATEX_HEADER: \usepackage{hyperref}
> #+LATEX_HEADER: \usepackage{setspace}
> #+LATEX_HEADER: \usepackage{libertine}
> #+LATEX_HEADER: \usepackage[left=1.5in,right=1.5in]{geometry}
> #+LATEX_HEADER: \setlength{\parskip}{1em}
> #+LATEX_HEADER: \setlength{\parindent}{0pt}
>
> # Insert your graphic here-- getting the scale right can take some work
> \includegraphics[scale=0.145]{Your LetterHead PNG/JPG}
>
> \hfill \today
>
> [ Greeting Here ]
>
> # I use setspace and onehalfspacing to control line spacing
> \onehalfspacing
>
> [ Insert Inflated Rhetoric About Here ]
>
> Yours sincerely,\\
>
> # Insert your sig here... ditto on scale.
> \includegraphics[scale=0.4]{Your Sig PNG/JPG}
>
> \textbf{Your Name}\\
> Illustrious Title\\
> Second Illustrious Title\\
> Etc.\\
>
>
> <
> <
> <
>
> > On Oct 30, 2018, at 7:29 AM, Jeff Filipovits <jrfilipovits@gmail.com>
> wrote:
> >
> > Would you mind sharing them? This is a problem I am trying to figure out
> as well.
> >
> > On Tue, Oct 30, 2018, 9:29 AM Eric S Fraga <esflists@gmail.com> wrote:
> > Matt,
> >
> > I've replied directly to you with some files.
> > --
> > Eric S Fraga via Emacs 27.0.50, Org release_9.1.13-783-g97fac4
> >
>
>

[-- Attachment #2: Type: text/html, Size: 3616 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: letterhead and signature in odt export
  @ 2018-10-30 15:56  7%         ` ckelty ckelty
  2018-10-31  1:26  0%           ` Matt Price
  0 siblings, 1 reply; 200+ results
From: ckelty ckelty @ 2018-10-30 15:56 UTC (permalink / raw)
  To: Jeff Filipovits; +Cc: emacs-orgmode

I don’t mess around with LibreOffice, but if you want to do it in Org, this is what I do and it works fine. Some of the preamble is superfluous— for various letters I’ve had to add other LaTeX packages…. 

ck


>
>
>

#+STARTUP: indent
#+LANGUAGE: en
#+OPTIONS: num:nil  toc:nil ':t
#+AUTHOR: Your Name Here
#+EMAIL: Your Email Here
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
#+LATEX_HEADER: \usepackage[T1]{fontenc}
#+LATEX_HEADER: \usepackage{graphicx}
#+LATEX_HEADER: \usepackage{float}
#+LATEX_HEADER: \usepackage{wrapfig}
#+LATEX_HEADER: \usepackage{rotating}
#+LATEX_HEADER: \usepackage[normalem]{ulem}
#+LATEX_HEADER: \usepackage{hyperref}
#+LATEX_HEADER: \usepackage{setspace}
#+LATEX_HEADER: \usepackage{libertine}
#+LATEX_HEADER: \usepackage[left=1.5in,right=1.5in]{geometry}
#+LATEX_HEADER: \setlength{\parskip}{1em}
#+LATEX_HEADER: \setlength{\parindent}{0pt}

# Insert your graphic here-- getting the scale right can take some work
\includegraphics[scale=0.145]{Your LetterHead PNG/JPG} 

\hfill \today

[ Greeting Here ]

# I use setspace and onehalfspacing to control line spacing
\onehalfspacing

[ Insert Inflated Rhetoric About Here ]

Yours sincerely,\\

# Insert your sig here... ditto on scale. 
\includegraphics[scale=0.4]{Your Sig PNG/JPG}

\textbf{Your Name}\\
Illustrious Title\\
Second Illustrious Title\\
Etc.\\


<
<
<

> On Oct 30, 2018, at 7:29 AM, Jeff Filipovits <jrfilipovits@gmail.com> wrote:
> 
> Would you mind sharing them? This is a problem I am trying to figure out as well. 
> 
> On Tue, Oct 30, 2018, 9:29 AM Eric S Fraga <esflists@gmail.com> wrote:
> Matt,
> 
> I've replied directly to you with some files.
> -- 
> Eric S Fraga via Emacs 27.0.50, Org release_9.1.13-783-g97fac4
> 

^ permalink raw reply	[relevance 7%]

* Re: exporting to latex and docx not honouring carriage returns to tabbing
  2018-10-09 21:31  0%           ` Tim Cross
@ 2018-10-11 13:24  0%             ` Sharon Kimble
  0 siblings, 0 replies; 200+ results
From: Sharon Kimble @ 2018-10-11 13:24 UTC (permalink / raw)
  To: Tim Cross; +Cc: org-mode-email, Robert Klein

[-- Attachment #1: Type: text/plain, Size: 6546 bytes --]

Tim Cross <theophilusx@gmail.com> writes:

> Sharon Kimble <boudiccas@skimble.plus.com> writes:
>
>> Eric S Fraga <esflists@gmail.com> writes:
>>
>>> On Tuesday,  9 Oct 2018 at 12:06, Sharon Kimble wrote:
>>>> Brilliant, thanks very much Robert, you've saved the project as I didn't
>>>> fancy having to work with the document in LibreOffice. These are the
>>>> settings that I've finally gone with -
>>>>
>>>> #+LaTeX_Header: \parskip=0pt
>>>> #+LaTeX_Header: \parindent=2em
>>>
>>> This is close to the default behaviour for the LaTeX article class.  Did you have something setting these to different values?
>>
>> Yes, I have a custom class called 'my-report' which has no packages
>> outlined in it, here it is.
>>
>> --8<---------------cut here---------------start------------->8---
>> #+begin_src emacs-lisp
>> (with-eval-after-load 'ox-latex
>> (add-to-list 'org-latex-classes
>>              '("my-report" "\\documentclass{report}
>>                [NO-DEFAULT-PACKAGES]"
>>                ;;[EXTRA]"
>>                ;;("\\part{%s}" . "\\part*{%s}")
>>                ("\\chapter{%s}" . "\\chapter*{%s}")
>>                ("\\section{%s}" . "\\section*{%s}")
>>                ("\\subsection{%s}" . "\\subsection*{%s}")
>>                ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
>>                ("\\paragraph{%s}" . "\\paragraph*{%s}")
>>                ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
>>               (custom-set-variables '(org-export-allow-bind-keywords t))
>> #+end_src
>> [2016-04-14 Thu 08:47]
>> [2016-09-09 Fri 00:54]
>> [2017-01-17 Tue 13:17]
>> http://orgmode.org/worg/org-tutorials/org-latex-export.html
>> --8<---------------cut here---------------end--------------->8---
>>
>>
>>>> except for the first paragraph in a new chapter.
>>>
>>> Yes, the first paragraph after any heading will not be indented.  That is also default and is actually what most books use.
>>
>> Yes, I'm learning, and checking with the book that I'm currently reading :)
>>
>> Thanks
>> Sharon.
>
> While Eric and Robert have provided some really useful tips on some
> ad-hoc tweaks you can make to latex/pdf output, I would also encourage
> you to look at the many other document styles. As Eric points out, the
> tweaks look to be changing the 'report' class to be more like the
> 'article' class. Have you tried just using the article class instead of
> report? Note also there is a 'book' class as well, which may well
> produce something more in line with what your after if you are wanting
> output which looks more like a published book. Then there are all the
> other 'publishers' styles to consider as well as other style packages
> like KomaScript, HiTec etc. 
>
> While these tweaks are often very useful, they really should be used
> sparingly as they can have unforeseen consequences, especially when you
> begin to use other packages. It is important to remember that some org
> features rely on some of these additional packages to produce good
> export results. Once you start 'tweaking' the output, it can quickly
> spiral out of control. You fix one thing only to create two new issues.
>
> One of the most common mistakes I see when people start using latex as
> the basis for document generation is ad hoc tweaking of the style. This
> is an unfortunate consequence of most of us being exposed to traditional
> word processors such as MS Word or Libre Office. Producing good quality
> documents is a very complex topic and Donald Knuth spent a lot of time
> researching all the aspects of type setting and layout to produce a
> consistently good and reliable system with TeX. Things have evolved and
> we have new requirements (such as on-line documents which are read
> electronically and not printed in hard copy). Additional packages have
> been added to address these types of enhancements. 
>
> The real trick with TeX/LaTeX is to work with the system and not against
> it. If you find it necessary to constantly tweak indent, paragraph
> spacing, line height, line breaks,  etc, then you are probably using the
> wrong document style. Try other styles and look for one which meets the
> majority of your requirements and only then consider tweaking it. As you
> will probably need more than one, you will likely end up with a number
> of custom definitions in addition to 'my-report'. I have around 5 base
> ones as well as a handful of ones specific to particular jobs/clients
> (e.g. include logos, custom headers/footers, title pages etc).
>
> The bad news is that this will probably be somewhat time consuming
> initially (there is a huge number of document styles and packages out
> there). The good news is that once you have the basic definitions, you
> probably won't have to think about this again for ages (my definitions
> have been in place for years now).
>
> good luck
>
> Tim

Thanks Tim, but I've been using Linux since sometime in 2003, and have
moved on from writing various things in 'pure' latex (meaning that it
wasn't exported into latex as it was already there!) to my current state
of writing in org-mode and exporting to latex. I've used my 'my-report'
class for the last 2 years at least with minimal problems, and am now
achieving layouts comparable with any fiction book you care to read off
the bookshop shelf now. I also install and use Tex-live into my \home
every year as it is released, and use a home-based mediawiki to develop
articles and layouts for mediawiki on the web. So to summarise, I have a
lot of history in linux and its available programs.

With regard to 'korma' that you and Eric both mentioned, it is something
that I've looked at, but only a very quick glance and play with, so I
don't know much about it. When, and if, I get time it is on my list of
things to try and investigate and learn more about. I may end up using
it in a book, I don't know yet.

The first distro that I used was Red Hat, and I bought a copy as that
was the only way in which you could get hold of it, and a couple of days
before I was going to install it, Red Hat made it free to download and
use! And that did not help my mood at all! But I've been trying to find
what year that was, can anyone tell me please, as I can't find a date
for it?

Thanks
Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
DrugFacts = https://www.drugfacts.org.uk
Debian 9.4, fluxbox 1.3.7, emacs 25.3.4, org 9.1.14

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: exporting to latex and docx not honouring carriage returns to tabbing
  2018-10-09 16:53  0%         ` Sharon Kimble
@ 2018-10-09 21:31  0%           ` Tim Cross
  2018-10-11 13:24  0%             ` Sharon Kimble
  0 siblings, 1 reply; 200+ results
From: Tim Cross @ 2018-10-09 21:31 UTC (permalink / raw)
  To: Sharon Kimble; +Cc: org-mode-email, Robert Klein


Sharon Kimble <boudiccas@skimble.plus.com> writes:

> Eric S Fraga <esflists@gmail.com> writes:
>
>> On Tuesday,  9 Oct 2018 at 12:06, Sharon Kimble wrote:
>>> Brilliant, thanks very much Robert, you've saved the project as I didn't
>>> fancy having to work with the document in LibreOffice. These are the
>>> settings that I've finally gone with -
>>>
>>> #+LaTeX_Header: \parskip=0pt
>>> #+LaTeX_Header: \parindent=2em
>>
>> This is close to the default behaviour for the LaTeX article class.  Did you have something setting these to different values?
>
> Yes, I have a custom class called 'my-report' which has no packages
> outlined in it, here it is.
>
> --8<---------------cut here---------------start------------->8---
> #+begin_src emacs-lisp
> (with-eval-after-load 'ox-latex
> (add-to-list 'org-latex-classes
>              '("my-report" "\\documentclass{report}
>                [NO-DEFAULT-PACKAGES]"
>                ;;[EXTRA]"
>                ;;("\\part{%s}" . "\\part*{%s}")
>                ("\\chapter{%s}" . "\\chapter*{%s}")
>                ("\\section{%s}" . "\\section*{%s}")
>                ("\\subsection{%s}" . "\\subsection*{%s}")
>                ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
>                ("\\paragraph{%s}" . "\\paragraph*{%s}")
>                ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
>               (custom-set-variables '(org-export-allow-bind-keywords t))
> #+end_src
> [2016-04-14 Thu 08:47]
> [2016-09-09 Fri 00:54]
> [2017-01-17 Tue 13:17]
> http://orgmode.org/worg/org-tutorials/org-latex-export.html
> --8<---------------cut here---------------end--------------->8---
>
>
>>> except for the first paragraph in a new chapter.
>>
>> Yes, the first paragraph after any heading will not be indented.  That is also default and is actually what most books use.
>
> Yes, I'm learning, and checking with the book that I'm currently reading :)
>
> Thanks
> Sharon.

While Eric and Robert have provided some really useful tips on some
ad-hoc tweaks you can make to latex/pdf output, I would also encourage
you to look at the many other document styles. As Eric points out, the
tweaks look to be changing the 'report' class to be more like the
'article' class. Have you tried just using the article class instead of
report? Note also there is a 'book' class as well, which may well
produce something more in line with what your after if you are wanting
output which looks more like a published book. Then there are all the
other 'publishers' styles to consider as well as other style packages
like KomaScript, HiTec etc. 

While these tweaks are often very useful, they really should be used
sparingly as they can have unforeseen consequences, especially when you
begin to use other packages. It is important to remember that some org
features rely on some of these additional packages to produce good
export results. Once you start 'tweaking' the output, it can quickly
spiral out of control. You fix one thing only to create two new issues.

One of the most common mistakes I see when people start using latex as
the basis for document generation is ad hoc tweaking of the style. This
is an unfortunate consequence of most of us being exposed to traditional
word processors such as MS Word or Libre Office. Producing good quality
documents is a very complex topic and Donald Knuth spent a lot of time
researching all the aspects of type setting and layout to produce a
consistently good and reliable system with TeX. Things have evolved and
we have new requirements (such as on-line documents which are read
electronically and not printed in hard copy). Additional packages have
been added to address these types of enhancements. 

The real trick with TeX/LaTeX is to work with the system and not against
it. If you find it necessary to constantly tweak indent, paragraph
spacing, line height, line breaks,  etc, then you are probably using the
wrong document style. Try other styles and look for one which meets the
majority of your requirements and only then consider tweaking it. As you
will probably need more than one, you will likely end up with a number
of custom definitions in addition to 'my-report'. I have around 5 base
ones as well as a handful of ones specific to particular jobs/clients
(e.g. include logos, custom headers/footers, title pages etc).

The bad news is that this will probably be somewhat time consuming
initially (there is a huge number of document styles and packages out
there). The good news is that once you have the basic definitions, you
probably won't have to think about this again for ages (my definitions
have been in place for years now).

good luck

Tim




--
Tim Cross

^ permalink raw reply	[relevance 0%]

* Re: exporting to latex and docx not honouring carriage returns to tabbing
  2018-10-09 13:11  0%       ` Eric S Fraga
@ 2018-10-09 16:53  0%         ` Sharon Kimble
  2018-10-09 21:31  0%           ` Tim Cross
  0 siblings, 1 reply; 200+ results
From: Sharon Kimble @ 2018-10-09 16:53 UTC (permalink / raw)
  To: Robert Klein; +Cc: org-mode-email

[-- Attachment #1: Type: text/plain, Size: 2033 bytes --]

Eric S Fraga <esflists@gmail.com> writes:

> On Tuesday,  9 Oct 2018 at 12:06, Sharon Kimble wrote:
>> Brilliant, thanks very much Robert, you've saved the project as I didn't
>> fancy having to work with the document in LibreOffice. These are the
>> settings that I've finally gone with -
>>
>> #+LaTeX_Header: \parskip=0pt
>> #+LaTeX_Header: \parindent=2em
>
> This is close to the default behaviour for the LaTeX article class.  Did you have something setting these to different values?

Yes, I have a custom class called 'my-report' which has no packages
outlined in it, here it is.

--8<---------------cut here---------------start------------->8---
#+begin_src emacs-lisp
(with-eval-after-load 'ox-latex
(add-to-list 'org-latex-classes
             '("my-report" "\\documentclass{report}
               [NO-DEFAULT-PACKAGES]"
               ;;[EXTRA]"
               ;;("\\part{%s}" . "\\part*{%s}")
               ("\\chapter{%s}" . "\\chapter*{%s}")
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
              (custom-set-variables '(org-export-allow-bind-keywords t))
#+end_src
[2016-04-14 Thu 08:47]
[2016-09-09 Fri 00:54]
[2017-01-17 Tue 13:17]
http://orgmode.org/worg/org-tutorials/org-latex-export.html
--8<---------------cut here---------------end--------------->8---


>> except for the first paragraph in a new chapter. 
>
> Yes, the first paragraph after any heading will not be indented.  That is also default and is actually what most books use.

Yes, I'm learning, and checking with the book that I'm currently reading :)

Thanks
Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
DrugFacts = https://www.drugfacts.org.uk
Debian 9.4, fluxbox 1.3.7, emacs 25.3.4, org 9.1.14

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: exporting to latex and docx not honouring carriage returns to tabbing
  2018-10-09 11:06  7%     ` Sharon Kimble
@ 2018-10-09 13:11  0%       ` Eric S Fraga
  2018-10-09 16:53  0%         ` Sharon Kimble
  0 siblings, 1 reply; 200+ results
From: Eric S Fraga @ 2018-10-09 13:11 UTC (permalink / raw)
  To: Sharon Kimble; +Cc: org-mode-email, Robert Klein

On Tuesday,  9 Oct 2018 at 12:06, Sharon Kimble wrote:
> Brilliant, thanks very much Robert, you've saved the project as I didn't
> fancy having to work with the document in LibreOffice. These are the
> settings that I've finally gone with -
>
> #+LaTeX_Header: \parskip=0pt
> #+LaTeX_Header: \parindent=2em

This is close to the default behaviour for the LaTeX article class.  Did you have something setting these to different values?

> except for the first paragraph in a new chapter. 

Yes, the first paragraph after any heading will not be indented.  That is also default and is actually what most books use.

-- 

Eric S Fraga via Emacs 27.0.50, Org release_9.1.13-783-g97fac4

^ permalink raw reply	[relevance 0%]

* Re: exporting to latex and docx not honouring carriage returns to tabbing
  2018-10-09  6:20 10%   ` Robert Klein
@ 2018-10-09 11:06  7%     ` Sharon Kimble
  2018-10-09 13:11  0%       ` Eric S Fraga
  0 siblings, 1 reply; 200+ results
From: Sharon Kimble @ 2018-10-09 11:06 UTC (permalink / raw)
  To: Robert Klein; +Cc: Eric S Fraga, org-mode-email

[-- Attachment #1: Type: text/plain, Size: 2650 bytes --]

Robert Klein <roklein@roklein.de> writes:

> On Mon, 08 Oct 2018 16:54:39 +0100
> Eric S Fraga <esflists@gmail.com> wrote:
>
>> On Monday,  8 Oct 2018 at 10:56, Sharon Kimble wrote:
>> > My finished output in the pdf will have every line indented/tabbed
>> > to 4 spaces and have a carriage-return at the end of each
>> > paragraph, with no spacings in between paragraphs.
>> >
>> > I can get it how I want in org-mode, but when its exported to latex
>> > and converted into a pdf file, the whole section comes out in one
>> > block of text!  
>> 
>> Both LaTeX and org define new paragraphs by a blank line.   Spaces at
>> the start of a line only have meaning, in org, if the lines are part
>> of a list (and never mean anything in LaTeX).
>> 
>> I am not sure exactly what you want to achieve so it is difficult to
>> suggest anything.  Try separating your paragraphs with empty lines to
>> see how much closer this gets you to what you want.
>> 
>
> What Eric says.
>
> Then try to add to the org-file a line
>
> #+LaTeX_Header: \parskip=0pt
>
> so the spacing between paragraphs is 0.  Then add
>
> #+LaTeX_Header: \parindent=0pt
>
> so the first line of a paragraph isn't indented.
>
> If you want to get /all/ the text indented by “4 spaces”, put a line
>
> #+LaTeX: \setlength{\leftskip}{2em}
>
> at the top of your document.
>
>
> If you want only parts indented, put the line before the beginning of
> the part to be indented and put this line after it:
>
> #+LaTeX: \setlength{\leftskip}{0em}
>
> Does this help?

Brilliant, thanks very much Robert, you've saved the project as I didn't
fancy having to work with the document in LibreOffice. These are the
settings that I've finally gone with -

--8<---------------cut here---------------start------------->8---
#+LaTeX_Header: \parskip=0pt
#+LaTeX_Header: \parindent=2em
--8<---------------cut here---------------end--------------->8---

and I've found that having that parindent of 2em gives a very close
approximation of each paragraph beginning with four spaces, except for
the first paragraph in a new chapter. Weird, but true! Just part of what
my finished document has to look like, open any fiction book and you see
what its supposed to look like. When it works right, its beautiful, but
when its wrong, its a right mare!

Thank you very much, and now I've learnt how to do it, it'll make the
whole thing much easier.

Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
DrugFacts = https://www.drugfacts.org.uk
Debian 9.4, fluxbox 1.3.7, emacs 25.3.4, org 9.1.14

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[relevance 7%]

* Re: exporting to latex and docx not honouring carriage returns to tabbing
  @ 2018-10-09  6:20 10%   ` Robert Klein
  2018-10-09 11:06  7%     ` Sharon Kimble
  0 siblings, 1 reply; 200+ results
From: Robert Klein @ 2018-10-09  6:20 UTC (permalink / raw)
  To: Eric S Fraga; +Cc: org-mode-email, Sharon Kimble

On Mon, 08 Oct 2018 16:54:39 +0100
Eric S Fraga <esflists@gmail.com> wrote:

> On Monday,  8 Oct 2018 at 10:56, Sharon Kimble wrote:
> > My finished output in the pdf will have every line indented/tabbed
> > to 4 spaces and have a carriage-return at the end of each
> > paragraph, with no spacings in between paragraphs.
> >
> > I can get it how I want in org-mode, but when its exported to latex
> > and converted into a pdf file, the whole section comes out in one
> > block of text!  
> 
> Both LaTeX and org define new paragraphs by a blank line.   Spaces at
> the start of a line only have meaning, in org, if the lines are part
> of a list (and never mean anything in LaTeX).
> 
> I am not sure exactly what you want to achieve so it is difficult to
> suggest anything.  Try separating your paragraphs with empty lines to
> see how much closer this gets you to what you want.
> 

What Eric says.

Then try to add to the org-file a line

#+LaTeX_Header: \parskip=0pt

so the spacing between paragraphs is 0.  Then add

#+LaTeX_Header: \parindent=0pt

so the first line of a paragraph isn't indented.

If you want to get /all/ the text indented by “4 spaces”, put a line

#+LaTeX: \setlength{\leftskip}{2em}

at the top of your document.


If you want only parts indented, put the line before the beginning of
the part to be indented and put this line after it:

#+LaTeX: \setlength{\leftskip}{0em}


Does this help?

Best regards
Robert

^ permalink raw reply	[relevance 10%]

* Custom checkboxes when exporting to beamer/latex
@ 2018-09-27  3:30  8% Adrian Bradd
  0 siblings, 0 replies; 200+ results
From: Adrian Bradd @ 2018-09-27  3:30 UTC (permalink / raw)
  To: emacs-org list


Hello,

I wanted to replace the cross with a tick (or any arbitrary 
symbol) in beamer/latex exports.

I took a look at `org-latex-item' which uses the :checkbox 
property to transcode between org and latex/beamer. Looks like I 
could change the :checkbox property to enable a custom checkbox, 
but this may break other backends.

As an alternative, redefining \boxtimes works as shown below:

#+begin_src org
#+TITLE: MWE
#+OPTIONS: H:1
#+LATEX_CLASS: beamer
#+COLUMNS: %45ITEM %10BEAMER_env(Env) %10BEAMER_act(Act) 
 %4BEAMER_col(Col) %8BEAMER_opt(Opt)
#+BEAMER_THEME: default
#+BEAMER_COLOR_THEME:
#+BEAMER_FONT_THEME:
#+BEAMER_INNER_THEME:
#+BEAMER_OUTER_THEME:
#+BEAMER_HEADER: 
 \renewcommand{\boxtimes}{\makebox[0pt][l]{\hspace{0.1em}\checkmark}$\square$}%

* Sample heading

- [X] Completed
- [ ] Trans
- [ ] 
#+end_src

This isn't optimal as the original \boxtimes is now unavailable.

Suggestions welcome.

-- 
Adrian Bradd

^ permalink raw reply	[relevance 8%]

* preview embedded latex fragments error with my settings
@ 2018-03-26 15:55  2% stardiviner
  0 siblings, 0 replies; 200+ results
From: stardiviner @ 2018-03-26 15:55 UTC (permalink / raw)
  To: org-mode


[-- Attachment #1.1: Type: text/plain, Size: 9158 bytes --]

I have following settings to make org-mode export to PDF works better, 
like export with src block syntax highlighting with "minted", and 
support Chinese export with latex package "ctex" and specify default 
font etc all stuffs.

I used to disabled org-mode startup preview latex fragments. Today I use 
[C-c C-x C-l] to preview latex fragments, it raised error (I shorten the 
error stack manuallyfor easy to read):

```

Debugger entered--Lisp error: (error "File \"/tmp/orgtexhCLnu9.dvi\" 
wasn’t produced.  Please adjust ‘dvisvgm’ part of 
‘org-preview-latex-process-alist’.")
   signal(error ("File \"/tmp/orgtexhCLnu9.dvi\" wasn’t produced.  
Please adjust ‘dvisvgm’ part of ‘org-preview-latex-process-alist’."))
   error("File \"/tmp/orgtexhCLnu9.dvi\" wasn't produced.  Please adjust 
`dvisvgm' part of `org-preview-latex-process-alist'.")
   (if (org-file-newer-than-p output time) nil (error (format "File %S 
wasn't produced%s" output err-msg)))
   (let* ((base-name (file-name-base source)) (full-name (file-truename 
source)) (out-dir (or (file-name-directory source) "./")) (output 
(expand-file-name (concat base-name "." ext) out-dir)) (time 
(current-time)) (err-msg (if (stringp err-msg) (concat ".  " err-msg) 
""))) (let ((wconfig (current-window-configuration))) (unwind-protect 
(progn (cond ((functionp process) (funcall process (shell-quote-argument 
source))) ((consp process) (let ((log-buf (and log-buf 
(get-buffer-create log-buf))) (spec (append spec (list (cons 98 
(shell-quote-argument base-name)) (cons 102 (shell-quote-argument 
source)) (cons 70 (shell-quote-argument full-name)) (cons 111 
(shell-quote-argument out-dir)) (cons 79 (shell-quote-argument 
output)))))) (let ((--dolist-tail-- process)) (while --dolist-tail-- 
(let ((command (car --dolist-tail--))) (shell-command (format-spec 
command spec) log-buf) (setq --dolist-tail-- (cdr --dolist-tail--))))) 
(if log-buf (progn (save-current-buffer (set-buffer log-buf) 
(compilation-mode)))))) (t (error "No valid command to process %S%s" 
source err-msg)))) (set-window-configuration wconfig))) (if 
(org-file-newer-than-p output time) nil (error (format "File %S wasn't 
produced%s" output err-msg))) output)
   org-compile-file("/tmp/orgtexhCLnu9.tex" ("latex -interaction 
nonstopmode -output-directory %o %f") "dvi" "Please adjust `dvisvgm' 
part of `org-preview-latex-process-alist'." #<buffer *Org Preview LaTeX 
Output*>)
   (let* ((err-msg (format "Please adjust `%s' part of 
`org-preview-latex-process-alist'." processing-type)) ...... (let 
((--dolist-tail-- post-clean)) (while --dolist-tail-- (let ((e (car 
--dolist-tail--))) (if (file-exists-p (concat texfilebase e)) (progn 
(delete-file (concat texfilebase e)))) (setq --dolist-tail-- (cdr 
--dolist-tail--))))) image-output-file))
   org-create-formula-image("$\\LaTeX$" 
"/home/stardiviner/Org/Projects/Programming 
Projects/ltximg/org-ltximg_033e468d0c9a55db5895a459bfaa279c4e322eb9.svg" 
(:foreground default :background default :scale 2.0 :html-foreground 
"Black" :html-background "Transparent" :html-scale 2.5 :matchers 
("begin" "$1" "$" "$$" "\\(" "\\[")) forbuffer dvisvgm)
   (if (file-exists-p movefile) nil (org-create-formula-image value 
movefile options forbuffer processing-type))
   (let* ((processing-info (cdr (assq processing-type 
org-preview-latex-process-alist))) (face (face-at-point)) (fg (let 
((color (plist-get org-format-latex-options :foreground))) (if (and 
forbuffer (eq color 'auto)) (face-attribute face :foreground nil 
'default) color)))..... (delete-region beg end) (insert 
(org-format-latex-as-mathml value block-type prefix dir))) (t (error 
"Unknown conversion process %s for LaTeX fragments" processing-type)))
   (let ((block-type (eq type 'latex-environment)) (value 
(org-element-property :value context)) (beg (org-element-property :begin 
context)) (end (save-excursion (goto-char (org-element-property :end 
context))......(goto-char beg) (delete-region beg end) (insert 
(org-format-latex-as-mathml value block-type prefix dir))) (t (error 
"Unknown conversion process %s for LaTeX fragments" processing-type))))
   (progn (let ((block-type (eq type 'latex-environment)) (value 
(org-element-property :value context))...... (setq cnt (1+ cnt)) (if msg 
(progn (message msg cnt))) (goto-char beg) (delete-region beg end) 
(insert (org-format-latex-as-mathml value block-type prefix dir))) (t 
(error "Unknown conversion process %s for LaTeX fragments" 
processing-type)))))
   (if (memq type '(latex-environment latex-fragment)) (progn (let 
((block-type (eq type 'latex-environment)) (value (org-element-property 
:value context)) (beg (org-element-property :begin context))..... (t 
(error "Unknown conversion process %s for LaTeX fragments" 
processing-type))))))
   (let* ((context (org-element-context)) (type (org-element-type 
context))) (if (memq type '(latex-environment latex-fragment)) (progn 
(let ((block-type (eq type 'latex-environment))...... (setq cnt (1+ 
cnt)) (if msg (progn (message msg cnt))) (goto-char beg) (delete-region 
beg end) (insert (org-format-latex-as-mathml value block-type prefix 
dir))) (t (error "Unknown conversion process %s for LaTeX fragments" 
processing-type)))))))
   (if (and overlays (eq (get-char-property (point) 'org-overlay-type) 
'org-latex-overlay)) nil (let* ((context (org-element-context)) (type 
(org-element-type context)))..... (goto-char beg) (delete-region beg 
end) (insert (org-format-latex-as-mathml value block-type prefix dir))) 
(t (error "Unknown conversion process %s for LaTeX fragments" 
processing-type))))))))
   (while (re-search-forward math-regexp end t) (if (and overlays (eq 
(get-char-property (point) 'org-overlay-type) 'org-latex-overlay)) nil 
(let* ((context (org-element-context))......... (setq cnt (1+ cnt)) (if 
msg (progn (message msg cnt))) (goto-char beg) (delete-region beg end) 
(insert (org-format-latex-as-mathml value block-type prefix dir))) (t 
(error "Unknown conversion process %s for LaTeX fragments" 
processing-type))))))))))
   (if (eq processing-type 'verbatim) nil (let* ((math-regexp 
"\\$\\|\\\\[([]\\|^[ \11]*\\\\begin{[A-Za-z0-9*]+}") (cnt 0) 
checkdir-flag) (goto-char (or beg (point-min))) (if (and overlays (memq 
processing-type '(dvipng imagemagick))) (progn (overlay-recenter (or end 
(point-max))))).....(goto-char beg) (delete-region beg end) (insert 
(org-format-latex-as-mathml value block-type prefix dir))) (t (error 
"Unknown conversion process %s for LaTeX fragments" 
processing-type)))))))))))
   org-format-latex("ltximg/org-ltximg" 160825 160845 
"/home/stardiviner/Org/Projects/Programming Projects/" overlays 
"Creating images for section..." forbuffer dvisvgm)
   (let ((file (buffer-file-name (buffer-base-buffer)))) 
(org-format-latex (concat org-preview-latex-image-directory 
"org-ltximg") beg end (if (or (not file) (file-remote-p file)) 
temporary-file-directory default-directory) 'overlays msg 'forbuffer 
org-preview-latex-default-process))
   (let (beg end msg)..... 'overlays msg 'forbuffer 
org-preview-latex-default-process)) (message (concat msg "done")))
   (save-excursion (let (beg end msg) (cond ((or (equal arg '(16)) (and 
(equal arg '(4)) (progn (defvar org-called-with-limited-levels) (defvar 
org-outline-regexp) (defvar outline-regexp) (defvar 
org-outline-regexp-bol) (let* ((org-called-with-limited-levels t) 
(org-outline-regexp (org-get-limited-outline-regexp)) (outline-regexp 
org-outline-regexp)..... beg end (if (or (not file) (file-remote-p 
file)) temporary-file-directory default-directory) 'overlays msg 
'forbuffer org-preview-latex-default-process)) (message (concat msg 
"done"))))
   (catch 'exit (save-excursion (let (beg end msg) (cond ((or (equal arg 
'(16)) (and (equal arg '(4)) (progn (defvar 
org-called-with-limited-levels) (defvar 
org-outline-regexp).....(org-format-latex (concat 
org-preview-latex-image-directory "org-ltximg") beg end (if (or (not 
file) (file-remote-p file)) temporary-file-directory default-directory) 
'overlays msg 'forbuffer org-preview-latex-default-process)) (message 
(concat msg "done"))))))
   (if (display-graphic-p) (progn (catch 'exit (save-excursion (let (beg 
end msg) (cond ((or (equal arg '(16)) (and (equal arg '(4)) (progn 
(defvar org-called-with-limited-levels) (defvar org-outline-regexp) 
(defvar outline-regexp) (defvar org-outline-regexp-bol)..... (progn 
(message "LaTeX fragment images removed from section") (throw 'exit 
nil)) (setq msg "Creating images for section...")))))) (let ((file 
(buffer-file-name (buffer-base-buffer)))) (org-format-latex (concat 
org-preview-latex-image-directory "org-ltximg") beg end (if (or (not 
file) (file-remote-p file)) temporary-file-directory default-directory) 
'overlays msg 'forbuffer org-preview-latex-default-process)) (message 
(concat msg "done")))))))
   org-toggle-latex-fragment(nil)
   funcall-interactively(org-toggle-latex-fragment nil)
   call-interactively(org-toggle-latex-fragment nil nil)
   command-execute(org-toggle-latex-fragment)
```


The attachment is a simple config that you can reproduce this problem.


[-- Attachment #1.2: Type: text/html, Size: 17815 bytes --]

[-- Attachment #2: reproduce-config.el --]
[-- Type: text/x-emacs-lisp, Size: 4263 bytes --]

(setq org-preview-latex-default-process 'dvisvgm) ; generate SVG for better image.
(setq org-latex-image-default-width "2.0\\linewidth")
(setq org-format-latex-options
      (plist-put org-format-latex-options :scale 2.0)) ; adjust LaTeX preview image size.
(setq org-format-latex-options
      (plist-put org-format-latex-options :html-scale 2.5)) ; adjust HTML exporting LaTeX image size.

;;; Org export to LaTeX default headers.
;; set LaTeX default font
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\setmainfont{DejaVu Sans}"))
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\setsansfont{DejaVu Serif}"))
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\setmonofont{DejaVu Sans Mono}"))

;;; export to PDF with src blocks syntax highlighting.
(setq org-latex-listings 'minted)
(add-to-list 'org-latex-packages-alist '("" "minted"))
(setq org-latex-minted-options
      '(("frame" "lines")
        ("linenos" "true") ; enable number lines
        ;; ("frame" "single") ; box frame
        ("escapeinside" "$$") ; escape to LaTeX between the two characters specified in $$.
        ("mathescape" "true") ; escape and interrupt math in src block
        ("texcomments" "true") ; enable LaTeX code inside comments
        ("numbersep" "5pt") ; gap between numbers and start of line
        ("framesep" "2mm") ; distance between frame and content
        ;; ("fontsize" "??") ; font size in code block
        ("breaklines" "true")
        ))
;; (add-to-list 'org-latex-minted-langs '(clojure "Clojure"))
;; (add-to-list 'org-latex-pdf-process
;;                "latexmk -shell-escape -bibtex -xelatex -g -f %f")
;;; Org-mode export to -> Chinese TeX (ctex) -> PDF
;;; set default LaTeX engine to xetex
(setq-default TeX-engine 'xetex)
(add-to-list 'org-latex-packages-alist '("" "ctex"))
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\usepackage[utf8]{ctex}"))
;; (setq org-format-latex-header
;;       (concat org-format-latex-header "\n" "\\usepackage{xeCJK}"))
;;; set latex to xelatex engine.
(setq org-latex-pdf-process
      '("xelatex -8bit --shell-escape  -interaction=nonstopmode -output-directory %o %f"
        "xelatex -8bit --shell-escape  -interaction=nonstopmode -output-directory %o %f"
        "xelatex -8bit --shell-escape  -interaction=nonstopmode -output-directory %o %f"))
;; specify src block syntax highlighting color scheme
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\usemintedstyle{manni}"))
;; set src block
(setq org-format-latex-header
      (concat org-format-latex-header "\n"
              "\\lstset{frame=shadowbox,
numbers=left,
numberstyle= \\tiny,
keywordstyle= \\color{ blue!70},commentstyle=\\color{red!50!green!50!blue!50},
rulesepcolor= \\color{ red!20!green!20!blue!20}"))

;;; support for export Chinese LaTeX to PDF
(setf org-latex-default-packages-alist
      (remove '("AUTO" "inputenc" t ("pdflatex")) org-latex-default-packages-alist))
;;; set font for Chinese
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\usepackage{fontspec}"))
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\setCJKmainfont[scale=0.6]{WenQuanYi Micro Hei}"))
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\setCJKsansfont{WenQuanYi Micro Hei}"))
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\setCJKmonofont{WenQuanYi Micro Hei Mono}"))
;; set PDF file default font size. (Chinese)
(setq org-format-latex-header
      (replace-regexp-in-string
       "documentclass{article}"
       "documentclass[fontsize=5pt]{article}"
       org-format-latex-header))
;; Chinese linebreak
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\XeTeXlinebreaklocale \"zh\""))
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\XeTeXlinebreakskip = 0pt plus 1pt minus 0.1pt"))
;; CJKulem
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\usepackage{CJKulem}"))
;; page style
(add-to-list 'org-latex-packages-alist '("" "fancyhdr"))
(setq org-format-latex-header
      (concat org-format-latex-header "\n" "\\pagestyle{fancy}"))

^ permalink raw reply	[relevance 2%]

* preview embedded latex fragments error with my settings
@ 2018-03-26 15:49  2% stardiviner
  0 siblings, 0 replies; 200+ results
From: stardiviner @ 2018-03-26 15:49 UTC (permalink / raw)
  To: org-mode

[-- Attachment #1: Type: text/plain, Size: 12284 bytes --]

I have following settings to make org-mode export to PDF works better, 
like export with src block syntax highlighting with "minted", and 
support Chinese export with latex package "ctex" and specify default 
font etc all stuffs.

I used to disabled org-mode startup preview latex fragments. Today I use 
[C-c C-x C-l] to preview latex fragments, it raised error (I shorten the 
very long error stack):

```

Debugger entered--Lisp error: (error "File \"/tmp/orgtexhCLnu9.dvi\" 
wasn’t produced.  Please adjust ‘dvisvgm’ part of 
‘org-preview-latex-process-alist’.")
   signal(error ("File \"/tmp/orgtexhCLnu9.dvi\" wasn’t produced.  
Please adjust ‘dvisvgm’ part of ‘org-preview-latex-process-alist’."))
   error("File \"/tmp/orgtexhCLnu9.dvi\" wasn't produced.  Please adjust 
`dvisvgm' part of `org-preview-latex-process-alist'.")
   (if (org-file-newer-than-p output time) nil (error (format "File %S 
wasn't produced%s" output err-msg)))
   (let* ((base-name (file-name-base source)) (full-name (file-truename 
source)) (out-dir (or (file-name-directory source) "./")) (output 
(expand-file-name (concat base-name "." ext) out-dir)) (time 
(current-time)) (err-msg (if (stringp err-msg) (concat ".  " err-msg) 
""))) (let ((wconfig (current-window-configuration))) (unwind-protect 
(progn (cond ((functionp process) (funcall process (shell-quote-argument 
source))) ((consp process) (let ((log-buf (and log-buf 
(get-buffer-create log-buf))) (spec (append spec (list (cons 98 
(shell-quote-argument base-name)) (cons 102 (shell-quote-argument 
source)) (cons 70 (shell-quote-argument full-name)) (cons 111 
(shell-quote-argument out-dir)) (cons 79 (shell-quote-argument 
output)))))) (let ((--dolist-tail-- process)) (while --dolist-tail-- 
(let ((command (car --dolist-tail--))) (shell-command (format-spec 
command spec) log-buf) (setq --dolist-tail-- (cdr --dolist-tail--))))) 
(if log-buf (progn (save-current-buffer (set-buffer log-buf) 
(compilation-mode)))))) (t (error "No valid command to process %S%s" 
source err-msg)))) (set-window-configuration wconfig))) (if 
(org-file-newer-than-p output time) nil (error (format "File %S wasn't 
produced%s" output err-msg))) output)
   org-compile-file("/tmp/orgtexhCLnu9.tex" ("latex -interaction 
nonstopmode -output-directory %o %f") "dvi" "Please adjust `dvisvgm' 
part of `org-preview-latex-process-alist'." #<buffer *Org Preview LaTeX 
Output*>)
   (let* ((err-msg (format "Please adjust `%s' part of 
`org-preview-latex-process-alist'." processing-type)).... (progn 
(delete-file (concat texfilebase e)))) (setq --dolist-tail-- (cdr 
--dolist-tail--))))) image-output-file)
   (let* ((processing-type (or processing-type 
org-preview-latex-default-process)) (processing-info .... (setq 
--dolist-tail-- (cdr --dolist-tail--))))) image-output-file))
   org-create-formula-image("$\\LaTeX$" 
"/home/stardiviner/Org/Projects/Programming 
Projects/ltximg/org-ltximg_033e468d0c9a55db5895a459bfaa279c4e322eb9.svg" 
(:foreground default :background default :scale 2.0 :html-foreground 
"Black" :html-background "Transparent" :html-scale 2.5 :matchers 
("begin" "$1" "$" "$$" "\\(" "\\[")) forbuffer dvisvgm)
   (if (file-exists-p movefile) nil (org-create-formula-image value 
movefile options forbuffer processing-type))
   (let* ((processing-info (cdr (assq processing-type 
org-preview-latex-process-alist)))....... (goto-char beg) (delete-region 
beg end) (insert (org-format-latex-as-mathml value block-type prefix 
dir))) (t (error "Unknown conversion process %s for LaTeX fragments" 
processing-type)))
   (let ((block-type (eq type 'latex-environment)) (value 
(org-element-property :value context))..... (setq cnt (1+ cnt)) (if msg 
(progn (message msg cnt))) (goto-char beg) (delete-region beg end) 
(insert (org-format-latex-as-mathml value block-type prefix dir))) (t 
(error "Unknown conversion process %s for LaTeX fragments" 
processing-type))))
   (progn (let ((block-type (eq type 'latex-environment)) (value 
(org-element-property :value context)) ... (insert 
(org-format-latex-as-mathml value block-type prefix dir))) (t (error 
"Unknown conversion process %s for LaTeX fragments" processing-type)))))
   (if (memq type '(latex-environment latex-fragment)) (progn (let 
((block-type (eq type 'latex-environment)) (value (org-element-property 
:value context)) (beg (org-element-property :begin context)) (end 
(save-excursion (goto-char (org-element-property :end context)) 
(skip-chars-backward " \15\11\n") (point)))) (cond ((eq processing-type 
'mathjax).... (goto-char beg) (delete-region beg end) (insert 
(org-format-latex-as-mathml value block-type prefix dir))) (t (error 
"Unknown conversion process %s for LaTeX fragments" processing-type))))))
   (let* ((context (org-element-context)) (type (org-element-type 
context))) (if (memq type '(latex-environment latex-fragment)) (progn 
(let ((block-type (eq type 'latex-environment)) (value 
(org-element-property :value context)) (beg (org-element-property :begin 
context)).... ((eq processing-type 'mathml) (if 
(org-format-latex-mathml-available-p) nil (user-error "LaTeX to MathML 
converter not configured")) (setq cnt (1+ cnt)) (if msg (progn (message 
msg cnt))) (goto-char beg) (delete-region beg end) (insert 
(org-format-latex-as-mathml value block-type prefix dir))) (t (error 
"Unknown conversion process %s for LaTeX fragments" processing-type)))))))
   (if (and overlays (eq (get-char-property (point) 'org-overlay-type) 
'org-latex-overlay)) nil (let* ((context (org-element-context)) (type 
(org-element-type context))) (if (memq type '(latex-environment 
latex-fragment)) (progn (let ((block-type (eq type 'latex-environment)) 
(value (org-element-property :value context)) (beg (org-element-property 
:begin context)) (end (save-excursion (goto-char (org-element-property 
:end context))......(if msg (progn (message msg cnt))) (goto-char beg) 
(delete-region beg end) (insert (org-format-latex-as-mathml value 
block-type prefix dir))) (t (error "Unknown conversion process %s for 
LaTeX fragments" processing-type))))))))
   (while (re-search-forward math-regexp end t) (if (and overlays (eq 
(get-char-property (point) 'org-overlay-type) 'org-latex-overlay)) nil 
(let* ((context (org-element-context)) (type (org-element-type 
context))) (if (memq type '(latex-environment latex-fragment)).... (setq 
cnt (1+ cnt)) (if msg (progn (message msg cnt))) (goto-char beg) 
(delete-region beg end) (insert (org-format-latex-as-mathml value 
block-type prefix dir))) (t (error "Unknown conversion process %s for 
LaTeX fragments" processing-type)))))))))
   (let* ((math-regexp "\\$\\|\\\\[([]\\|^[ 
\11]*\\\\begin{[A-Za-z0-9*]+}") (cnt 0) checkdir-flag) (goto-char (or 
beg (point-min))) (if (and overlays (memq processing-type '(dvipng 
imagemagick))) (progn (overlay-recenter (or end (point-max))))).... 
(setq cnt (1+ cnt)) (if msg (progn (message msg cnt))) (goto-char beg) 
(delete-region beg end) (insert (org-format-latex-as-mathml value 
block-type prefix dir))) (t (error "Unknown conversion process %s for 
LaTeX fragments" processing-type))))))))))
   (if (eq processing-type 'verbatim) nil (let* ((math-regexp 
"\\$\\|\\\\[([]\\|^[ \11]*\\\\begin{[A-Za-z0-9*]+}") (cnt 0) 
checkdir-flag) (goto-char (or beg (point-min)))..... (t (error "Unknown 
conversion process %s for LaTeX fragments" processing-type)))))))))))
   org-format-latex("ltximg/org-ltximg" 160825 160845 
"/home/stardiviner/Org/Projects/Programming Projects/" overlays 
"Creating images for section..." forbuffer dvisvgm)
   (let ((file (buffer-file-name (buffer-base-buffer)))) 
(org-format-latex (concat org-preview-latex-image-directory 
"org-ltximg") beg end (if (or (not file) (file-remote-p file)) 
temporary-file-directory default-directory) 'overlays msg 'forbuffer 
org-preview-latex-default-process))
   (let (beg end msg) (cond ((or (equal arg '(16)) (and (equal arg '(4)) 
(progn (defvar org-called-with-limited-levels) (defvar 
org-outline-regexp) (defvar outline-regexp)..... (org-format-latex 
(concat org-preview-latex-image-directory "org-ltximg") beg end (if (or 
(not file) (file-remote-p file)) temporary-file-directory 
default-directory) 'overlays msg 'forbuffer 
org-preview-latex-default-process)) (message (concat msg "done")))
   (save-excursion (let (beg end msg) (cond ((or (equal arg '(16)) (and 
(equal arg '(4)) (progn (defvar org-called-with-limited-levels) (defvar 
org-outline-regexp) (defvar outline-regexp) (defvar 
org-outline-regexp-bol) (let* ((org-called-with-limited-levels t) 
(org-outline-regexp (org-get-limited-outline-regexp)) (outline-regexp 
org-outline-regexp) (org-outline-regexp-bol (concat "^" 
org-outline-regexp)))..... (let ((file (buffer-file-name 
(buffer-base-buffer)))) (org-format-latex (concat 
org-preview-latex-image-directory "org-ltximg") beg end (if (or (not 
file) (file-remote-p file)) temporary-file-directory default-directory) 
'overlays msg 'forbuffer org-preview-latex-default-process)) (message 
(concat msg "done"))))))
   (if (display-graphic-p) (progn (catch 'exit (save-excursion (let (beg 
end msg) (cond ((or (equal arg '(16)) (and (equal arg '(4)) (progn 
(defvar org-called-with-limited-levels) (defvar org-outline-regexp) 
(defvar outline-regexp) (defvar org-outline-regexp-bol) (let* 
((org-called-with-limited-levels t) (org-outline-regexp 
(org-get-limited-outline-regexp)) (outline-regexp org-outline-regexp) 
(org-outline-regexp-bol (concat "^" org-outline-regexp))) 
(org-before-first-heading-p)))))......(file-remote-p file)) 
temporary-file-directory default-directory) 'overlays msg 'forbuffer 
org-preview-latex-default-process)) (message (concat msg "done")))))))
   org-toggle-latex-fragment(nil)
   funcall-interactively(org-toggle-latex-fragment nil)
   call-interactively(org-toggle-latex-fragment nil nil)
   command-execute(org-toggle-latex-fragment)
```

Here is a simple version config might reproduce my problem:

```elisp

(setq org-preview-latex-default-process 'dvisvgm) ; generate SVG for 
better image.
(setq org-latex-image-default-width "2.0\\linewidth")
(setq org-format-latex-options
       (plist-put org-format-latex-options :scale 2.0)) ; adjust LaTeX 
preview image size.
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\setmainfont{DejaVu Sans}"))
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\setsansfont{DejaVu Serif}"))
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\setmonofont{DejaVu Sans 
Mono}"))
(setq-default TeX-engine 'xetex)
(add-to-list 'org-latex-packages-alist '("" "ctex"))
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\usepackage[utf8]{ctex}"))

;;; support for export Chinese LaTeX to PDF
(setf org-latex-default-packages-alist
       (remove '("AUTO" "inputenc" t ("pdflatex")) 
org-latex-default-packages-alist))
;;; set font for Chinese
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\usepackage{fontspec}"))
(setq org-format-latex-header
       (concat org-format-latex-header "\n" 
"\\setCJKmainfont[scale=0.6]{WenQuanYi Micro Hei}"))
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\setCJKsansfont{WenQuanYi 
Micro Hei}"))
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\setCJKmonofont{WenQuanYi 
Micro Hei Mono}"))
;; set PDF file default font size. (Chinese)
(setq org-format-latex-header
       (replace-regexp-in-string
        "documentclass{article}"
"documentclass[fontsize=5pt]{article}"
        org-format-latex-header))
;; Chinese linebreak
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\XeTeXlinebreaklocale 
\"zh\""))
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\XeTeXlinebreakskip = 0pt 
plus 1pt minus 0.1pt"))
;; CJKulem
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\usepackage{CJKulem}"))
;; page style
(add-to-list 'org-latex-packages-alist '("" "fancyhdr"))
(setq org-format-latex-header
       (concat org-format-latex-header "\n" "\\pagestyle{fancy}"))

```


[-- Attachment #2: Type: text/html, Size: 24808 bytes --]

^ permalink raw reply	[relevance 2%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-19  9:52  7%                         ` Eric S Fraga
@ 2018-03-25  0:23  7%                           ` Samuel Wales
  0 siblings, 0 replies; 200+ results
From: Samuel Wales @ 2018-03-25  0:23 UTC (permalink / raw)
  To: Samuel Wales, emacs-orgmode

i find that the following does not take effect the first time, but
works the second time.  not sure why that would be.

it looks much better now.  i think the main thing i would want is to
color links differently from the default red box, like maybe color the
text "#8968cd" and underline it so it looks kind of like a web page.

also, the pronoun "I" is boldface, which is disconcerting.  Acronyms
are also, but that is less disconcerting.

(add-to-list 'org-latex-classes
             '("article"
               "
\\documentclass{scrartcl}
% alpha is the single \ for these three correct?
\[DEFAULT-PACKAGES]
\[PACKAGES]
\[EXTRA]
\\setlength{\\parindent}{0pt}
\\setlength{\\parskip}{6pt}
"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))

> 1. Start your document with a top level heading, i.e. single * heading.

subtree.

> 2. Remove any whitespace before the \[...] entries in your
>    org-latex-classes setting.

this seemed to work [when i run it twice at least].  thank you!

aren't the single \ removed by emacs lisp's string object parsing?

^ permalink raw reply	[relevance 7%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-19  4:41  8%                       ` Samuel Wales
  2018-03-19  4:48  0%                         ` Samuel Wales
@ 2018-03-19  9:52  7%                         ` Eric S Fraga
  2018-03-25  0:23  7%                           ` Samuel Wales
  1 sibling, 1 reply; 200+ results
From: Eric S Fraga @ 2018-03-19  9:52 UTC (permalink / raw)
  To: Samuel Wales; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1484 bytes --]

On Sunday, 18 Mar 2018 at 21:41, Samuel Wales wrote:
> On 3/13/18, Eric S Fraga <esflists@gmail.com> wrote:
>> Could you post a minimal example that illustrates this?
>
> here is the minimal example.  [btw, it turns out that pandoc erros
> now, so i have to either get your direct export code to work, or fix
> pandoc's export.]

Couple of things:

1. Start your document with a top level heading, i.e. single * heading.
2. Remove any whitespace before the \[...] entries in your
   org-latex-classes setting.

For instance, this seems to work fine for me although obviously with no
real content it is difficult to see the settings taking effect:


* NEXTKA fixing pdf to have better paragraphs
SCHEDULED: <2018-03-21 Wed>

#+begin_src emacs-lisp
(add-to-list 'org-latex-classes
             '("article"
              "
\\documentclass{scrartcl}
\[DEFAULT-PACKAGES]
\[PACKAGES]
\[EXTRA]
\\setlength{\\parindent}{0pt}
\\setlength{\\parskip}{6pt}
"
                               ("\\section{%s}" . "\\section*{%s}")
                               ("\\subsection{%s}" . "\\subsection*{%s}")
                               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                               ("\\paragraph{%s}" . "\\paragraph*{%s}")
                               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
#+end_src

-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.1.7-475-g3ffc7d

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 194 bytes --]

^ permalink raw reply	[relevance 7%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-19  4:41  8%                       ` Samuel Wales
@ 2018-03-19  4:48  0%                         ` Samuel Wales
  2018-03-19  9:52  7%                         ` Eric S Fraga
  1 sibling, 0 replies; 200+ results
From: Samuel Wales @ 2018-03-19  4:48 UTC (permalink / raw)
  To: Samuel Wales, emacs-orgmode

[never mind the comment below..  if i use \\ instead of \, it doesn't
error, but produces default packages on the first page.  then the
document starts on the second page.]

On 3/18/18, Samuel Wales <samologist@gmail.com> wrote:
> On 3/13/18, Eric S Fraga <esflists@gmail.com> wrote:
>> Could you post a minimal example that illustrates this?
>
> here is the minimal example.  [btw, it turns out that pandoc erros
> now, so i have to either get your direct export code to work, or fix
> pandoc's export.]
>
> *********** NEXTKA fixing pdf to have better paragraphs
> SCHEDULED: <2018-03-21 Wed>
> #+begin_src emacs-lisp
> (add-to-list 'org-latex-classes
>              '("article"
>               "
>    \\documentclass{scrartcl}
>    % alpha is the single \ for these three erroneous?  but with \\ it
> errors.
>    \[DEFAULT-PACKAGES]
>    \[PACKAGES]
>    \[EXTRA]
>    \\setlength{\\parindent}{0pt}
>    \\setlength{\\parskip}{6pt}
> "
>                                ("\\section{%s}" . "\\section*{%s}")
>                                ("\\subsection{%s}" . "\\subsection*{%s}")
>                                ("\\subsubsection{%s}" .
> "\\subsubsection*{%s}")
>                                ("\\paragraph{%s}" . "\\paragraph*{%s}")
>                                ("\\subparagraph{%s}" .
> "\\subparagraph*{%s}")))
> #+end_src
>


-- 
The Kafka Pandemic: <http://thekafkapandemic.blogspot.com>

The disease DOES progress. MANY people have died from it. And ANYBODY
can get it at any time.

"You’ve really gotta quit this and get moving, because this is murder
by neglect." ---
<http://www.meaction.net/2017/02/03/pwme-people-with-me-are-being-murdered-by-neglect>.

^ permalink raw reply	[relevance 0%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  @ 2018-03-19  4:41  8%                       ` Samuel Wales
  2018-03-19  4:48  0%                         ` Samuel Wales
  2018-03-19  9:52  7%                         ` Eric S Fraga
  0 siblings, 2 replies; 200+ results
From: Samuel Wales @ 2018-03-19  4:41 UTC (permalink / raw)
  To: Samuel Wales, emacs-orgmode

On 3/13/18, Eric S Fraga <esflists@gmail.com> wrote:
> Could you post a minimal example that illustrates this?

here is the minimal example.  [btw, it turns out that pandoc erros
now, so i have to either get your direct export code to work, or fix
pandoc's export.]

*********** NEXTKA fixing pdf to have better paragraphs
SCHEDULED: <2018-03-21 Wed>
#+begin_src emacs-lisp
(add-to-list 'org-latex-classes
             '("article"
              "
   \\documentclass{scrartcl}
   % alpha is the single \ for these three erroneous?  but with \\ it errors.
   \[DEFAULT-PACKAGES]
   \[PACKAGES]
   \[EXTRA]
   \\setlength{\\parindent}{0pt}
   \\setlength{\\parskip}{6pt}
"
                               ("\\section{%s}" . "\\section*{%s}")
                               ("\\subsection{%s}" . "\\subsection*{%s}")
                               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                               ("\\paragraph{%s}" . "\\paragraph*{%s}")
                               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
#+end_src

^ permalink raw reply	[relevance 8%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-10  0:30  7%               ` Samuel Wales
@ 2018-03-12  9:42  8%                 ` Eric S Fraga
    0 siblings, 1 reply; 200+ results
From: Eric S Fraga @ 2018-03-12  9:42 UTC (permalink / raw)
  To: Samuel Wales; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1165 bytes --]

On Friday,  9 Mar 2018 at 17:30, Samuel Wales wrote:
> On 3/9/18, Eric S Fraga <esflists@gmail.com> wrote:
>> Type C-h v org-latex-classes RET for the full description.  The
>> header-string can include those particular indent and skip settings
>> along with other bits.
>
> i consulted the docstring and the manual.  the description was greek
> to me and there was no reference to qa term you used afaict.

Apologies for this.  Try the following (after loading org):

#+begin_src emacs-lisp
  (add-to-list 'org-latex-classes
               '("article" "\\documentclass{scrartcl}
    \[DEFAULT-PACKAGES]
    \[PACKAGES]
    \[EXTRA]
   \\setlength{\\parindent}{0pt}
   \\setlength{\\parskip}{6pt}
  "
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                 ("\\paragraph{%s}" . "\\paragraph*{%s}")
                 ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
#+end_src 

This should then work for default LaTeX export.


-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.1.6-191-g90607d

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 194 bytes --]

^ permalink raw reply	[relevance 8%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-10  0:05  0%             ` Eric S Fraga
@ 2018-03-10  0:30  7%               ` Samuel Wales
  2018-03-12  9:42  8%                 ` Eric S Fraga
  0 siblings, 1 reply; 200+ results
From: Samuel Wales @ 2018-03-10  0:30 UTC (permalink / raw)
  To: Samuel Wales, emacs-orgmode

On 3/9/18, Eric S Fraga <esflists@gmail.com> wrote:
> Type C-h v org-latex-classes RET for the full description.  The
> header-string can include those particular indent and skip settings
> along with other bits.

i consulted the docstring and the manual.  the description was greek
to me and there was no reference to qa term you used afaict.

but i figured out that article is the default and now know that you
want me to change header-string in that.  so i did this:

(with-eval-after-load 'org-latex
  (setf (second (assoc "article" org-latex-classes))
        ;; non-idempotent is undesirable
        (concat "\\setlength{\\parindent}{0pt}\\setlength{\\parskip}{6pt}"
                ;; repeating this form is undesirable
                (second (assoc "article" org-latex-classes)))))

which seems to set the variable correctly but has no effect.

it's ok to drop this.  i am limited in computer use and cannot sustain
more debugging cycles.

thanks for your help.

^ permalink raw reply	[relevance 7%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-09 20:26  7%           ` Samuel Wales
@ 2018-03-10  0:05  0%             ` Eric S Fraga
  2018-03-10  0:30  7%               ` Samuel Wales
  0 siblings, 1 reply; 200+ results
From: Eric S Fraga @ 2018-03-10  0:05 UTC (permalink / raw)
  To: Samuel Wales; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1005 bytes --]

On Friday,  9 Mar 2018 at 13:26, Samuel Wales wrote:

[...]

> in any case, greek to me.  this was my best guess.
>
> (with-eval-after-load
> (add-to-list org-latex-classes
> '("org-latex" "\setlength{\parindent}{0pt}\setlength{\parskip}{6pt}")))

No, this won't work.  You need to check the documentation for the
variable to see the structure that is expected:

org-latex-classes is a variable defined in ‘ox-latex.el’.
Its value is shown below.

Documentation:
Alist of LaTeX classes and associated header and structure.
If #+LATEX_CLASS is set in the buffer, use its value and the
associated information.  Here is the structure of each cell:

  (class-name
    header-string
    (numbered-section . unnumbered-section)
    ...)

(continues)

Type C-h v org-latex-classes RET for the full description.  The
header-string can include those particular indent and skip settings
along with other bits.

-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.1.6-191-g90607d

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 194 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-09  6:34  0%         ` Eric S Fraga
@ 2018-03-09 20:26  7%           ` Samuel Wales
  2018-03-10  0:05  0%             ` Eric S Fraga
  0 siblings, 1 reply; 200+ results
From: Samuel Wales @ 2018-03-09 20:26 UTC (permalink / raw)
  To: Samuel Wales, emacs-orgmode

On 3/8/18, Eric S Fraga <esflists@gmail.com> wrote:
> On Thursday,  8 Mar 2018 at 12:55, Samuel Wales wrote:
>> On 3/3/18, Eric S Fraga <esflists@gmail.com> wrote:
>>> #+latex_header: \setlength{\parindent}{0pt}\setlength{\parskip}{6pt}

>> are there settings in .emacs that will do the same thing?
>
> Yes, you can put such commands in the definition of the org-latex
> class.  Check org-latex-classes.

just feedback on the manual and the docstring, but i found nothing
about an org-latex class.  perhaps i wasn't supposed to?  in my latex
ignorance i think a class is probably like article, etc.  maybe
org-latex is a generic thing that gets put in front of article or
something.

in any case, greek to me.  this was my best guess.

(with-eval-after-load
(add-to-list org-latex-classes
'("org-latex" "\setlength{\parindent}{0pt}\setlength{\parskip}{6pt}")))

this isn't critical enough for me to pursue it further as i can use
html export and then pandoc, but maybe the doc could say what
org-latex class is.

>>> A table of contents will probably only be generated if you have not
>>> turned of heading numbering.

this is interesting.  i wonder why.

>> interesting.  i have 2 tables of contents for the same document.  [1
>> level at front and complete at end.]  i have num:t in properties
>> drawer.
>>
>> in html, both export.  in pdf, only the first exports.
>
> Cannot help here.  Sorry.

ok.  :].  thanks.

^ permalink raw reply	[relevance 7%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-08 19:55  0%       ` Samuel Wales
@ 2018-03-09  6:34  0%         ` Eric S Fraga
  2018-03-09 20:26  7%           ` Samuel Wales
  0 siblings, 1 reply; 200+ results
From: Eric S Fraga @ 2018-03-09  6:34 UTC (permalink / raw)
  To: Samuel Wales; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 945 bytes --]

On Thursday,  8 Mar 2018 at 12:55, Samuel Wales wrote:
> On 3/3/18, Eric S Fraga <esflists@gmail.com> wrote:
>> #+latex_header: \setlength{\parindent}{0pt}\setlength{\parskip}{6pt}
>>
>> might give you "unbunched" "unindented" paragraphs.
>
> thank you.  i will try that when i can.
>
> are there settings in .emacs that will do the same thing?

Yes, you can put such commands in the definition of the org-latex
class.  Check org-latex-classes.

>> A table of contents will probably only be generated if you have not
>> turned of heading numbering.  You can turn this on explicitly by
>>
>> #+options: toc:t num:t
>
> interesting.  i have 2 tables of contents for the same document.  [1
> level at front and complete at end.]  i have num:t in properties
> drawer.
>
> in html, both export.  in pdf, only the first exports.

Cannot help here.  Sorry.

-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.1.6-191-g90607d

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 194 bytes --]

^ permalink raw reply	[relevance 0%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  2018-03-03 11:26  8%     ` Eric S Fraga
@ 2018-03-08 19:55  0%       ` Samuel Wales
  2018-03-09  6:34  0%         ` Eric S Fraga
  0 siblings, 1 reply; 200+ results
From: Samuel Wales @ 2018-03-08 19:55 UTC (permalink / raw)
  To: Samuel Wales, emacs-orgmode

On 3/3/18, Eric S Fraga <esflists@gmail.com> wrote:
> #+latex_header: \setlength{\parindent}{0pt}\setlength{\parskip}{6pt}
>
> might give you "unbunched" "unindented" paragraphs.

thank you.  i will try that when i can.

are there settings in .emacs that will do the same thing?

> A table of contents will probably only be generated if you have not
> turned of heading numbering.  You can turn this on explicitly by
>
> #+options: toc:t num:t

interesting.  i have 2 tables of contents for the same document.  [1
level at front and complete at end.]  i have num:t in properties
drawer.

in html, both export.  in pdf, only the first exports.

^ permalink raw reply	[relevance 0%]

* Re: what settings would make original export to pdf as good as pandoc conversion?
  @ 2018-03-03 11:26  8%     ` Eric S Fraga
  2018-03-08 19:55  0%       ` Samuel Wales
  0 siblings, 1 reply; 200+ results
From: Eric S Fraga @ 2018-03-03 11:26 UTC (permalink / raw)
  To: Samuel Wales; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 712 bytes --]

On Friday,  2 Mar 2018 at 11:53, Samuel Wales wrote:
> On 3/2/18, Eric S Fraga <esflists@gmail.com> wrote:
>> Why can you not use any LaTeX settings?  Org has very extensive support
>> for allowing tweaking of the formatting.
>
> delighted to learn of settings.

So, I am not sure what it is you want to do but maybe a line along the
lines of

#+latex_header: \setlength{\parindent}{0pt}\setlength{\parskip}{6pt}

might give you "unbunched" "unindented" paragraphs.

A table of contents will probably only be generated if you have not
turned of heading numbering.  You can turn this on explicitly by

#+options: toc:t num:t

-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.1.6-191-g90607d

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 194 bytes --]

^ permalink raw reply	[relevance 8%]

* Re: How to wavy/double underline an org-mode link?
  @ 2017-07-24 13:22  6%   ` Sharon Kimble
  0 siblings, 0 replies; 200+ results
From: Sharon Kimble @ 2017-07-24 13:22 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 3110 bytes --]

Eric S Fraga <e.fraga@ucl.ac.uk> writes:

> On Saturday, 22 Jul 2017 at 10:35, Sharon Kimble wrote:
>
> [...]
>
>> I've found that I can underline each org-mode link by putting '_' before
>> and after each link, which is then exported to a latex file and built
>> into the pdf and does work. But, I am already underlining each glossary
>> entry in the main body of the text, so to differentiate I would like
>> either a wavy underline, or a double underline. But how please?
>
> Have a look at org-link-parameters variable and this page for LaTeX
> suggestions on how to double-underline:
>
> http://tex.stackexchange.com/questions/249616/ddg#249617

Thanks to Eric and Rasmus who replied.

I did try using a double-underline but it looked so horrible I changed
it very quickly!

This is what I've ended up using -

--8<---------------cut here---------------start------------->8---

%% https://tex.stackexchange.com/questions/311132/how-to-style-hrefs-underlined-and-coloured-throughout-the-document?noredirect=1&lq=1

\usepackage{ulem}

\makeatletter
\begingroup
  \catcode`\$=6 %
  \catcode`\#=12 %
  \gdef\href@split$1#$2#$3\\$4{%
    \hyper@@link{$1}{$2}{\dashuline{$4}}% or \underline
    \endgroup
  }%
\endgroup
\makeatother

%% https://tex.stackexchange.com/questions/49862/having-all-links-underlined-with-dotted-line?noredirect=1&lq=1

\usetikzlibrary{calc}

\makeatletter
\newlength\link@width
\newsavebox\link@box

\newcommand{\formatlink}[1]{%
   % --- save the box to be displayed (so that e.g. footnote counters do not
   %     get incremented twice)
   \savebox{\link@box}{#1}%
   % --- calculate the width of the box for later use
   \settowidth\link@width{\usebox{\link@box}}%
   % --- draw the link
   \tikz[baseline=(todotted.base)]{
   \node[inner sep=-1pt,outer sep=0pt] (todotted) {\usebox{\link@box}};
   \draw[dotted, thick] 
      ($(todotted.base)-(.5\link@width,2pt)$) -- +(\link@width,0); 
   }%
}

\AtBeginDocument{%
   % --- replace \ref command
   % \let\oldref=\ref
   % \renewcommand\ref[1]{\formatlink{\oldref{#1}}}
   % --- replace hyperref command
   \let\oldhyperref=\hyperref
   \renewcommand\hyperref[2][]{\formatlink{\oldhyperref[#1]{#2}}}
   % --- replace footnote command
   % \let\oldfootnote=\footnote
   % \renewcommand\footnote[1]{\formatlink{\footnotemark}\footnotetext{#1}}
   % --- replace cite command
   % \let\oldcite=\cite
   % \renewcommand\cite[1]{\formatlink{\oldcite{#1}}}
   % --- introduce secref command   
   % \newcommand\secref[1]{\hyperref[#1]{Section \oldref{#1}}}
}
\makeatother
--8<---------------cut here---------------end--------------->8---

I've saved it as 'code-1.tex' and just use it as '#+latex_header:
\input{/home/boudiccas/research/code-1}' at the end of my package list
in my org-mode source document.

And its now working perfectly. 

Thanks
Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
DrugFacts = https://www.drugfacts.org.uk  
Debian 9.0, fluxbox 1.3.5-2, emacs 25.1.1, org-mode 9.0.9

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[relevance 6%]

* minitocs not displaying in latex export
@ 2017-06-28 21:47 11% Sharon Kimble
  0 siblings, 0 replies; 200+ results
From: Sharon Kimble @ 2017-06-28 21:47 UTC (permalink / raw)
  To: org-mode-email

[-- Attachment #1: Type: text/plain, Size: 5021 bytes --]


I'm having great difficulties in getting minitocs appearing in my chapters. This is my preamble -

--8<---------------cut here---------------start------------->8---
#+LaTeX_class: my-report
#+latex_header: \usepackage[a4paper,left=25mm,right=25mm,top=25mm,bottom=30mm,footskip=5mm,headsep=2mm]{geometry}
#+latex_header: \input{/home/boudiccas/research/hormones/hormones18/titlepage}
#+LATEX_CLASS_OPTIONS: [a4paper,11pt,oneside,openany,british,svgnames,dvipsnames]
#+latex_header: \usepackage[backend=biber,style=authoryear,doi=true,hyperref=true,backref=true,backrefstyle=two,date=year,maxcitenames=3]{biblatex}
#+LATEX_HEADER: \addbibresource{/home/boudiccas/research/hormones/hormones18/hormones18.bib}
#+latex_header: \input{/home/boudiccas/research/codebase}
#+latex_header: \makeindex[title=General Index,options=-s ./index.ist,columnseprule,intoc]
#+latex_header: \makeindex[name=horm,title=Index of Hormones,options=-s ./index.ist,columnseprule,intoc,columns=2]
#+latex_header: \makeindex[name=side,title=Index of Hormones Side-Effects,options=-s ./index.ist,columnseprule,intoc,columns=2]
#+latex_header: \makeindex[name=inter,title=Index of Interactions,options=-s ./index.ist,columnseprule,intoc,columns=2]
#+latex_header: \usepackage{bookmark,hyperref}
#+latex_header: \hypersetup{linktoc=all,colorlinks,linkcolor={red},citecolor={magenta},urlcolor={blue}}
#+latex_header: \usepackage[toc,nopostdot,style=listgroup]{glossaries}
#+latex_header: \input{hormones18.glos}
#+latex_header: \makeglossaries
#+latex_header: \glsenablehyper
#+latex_header: \renewcommand{\glstextformat}[1]{\underline{\color{red}\em #1}}
#+latex_header: \usepackage{todo}
#+latex_header: \usepackage[nostamp,firstpage]{draftwatermark}
#+LaTeX_header: \setcounter{secnumdepth}{1}
#+latex_header: \setcounter{tocdepth}{1}
#+latex_header: \usepackage{everypage}
#+latex_header: \usepackage{booktabs}
#+latex_header: \usepackage[mark]{gitinfo2}
#+latex_header: \usepackage{upgreek}
#+latex_header: \usepackage{pifont}
#+latex_header: \usepackage{textgreek}

#+latex_header: \usepackage{bookmark}
#+latex_header: \usepackage{color,soul,xcolor}
#+latex_header: \usepackage{caption}
#+latex_header: \setlength\parindent{0pt} % sets indent to zero
#+latex_header: \usepackage{chngcntr}
#+latex_header: \counterwithout{footnote}{chapter}
#+latex_header: \usepackage[Lenny]{fncychap} 
#+latex_header: \usepackage[toc]{multitoc}
#+latex_header: \usepackage{minibox}
#+latex_header: \renewcommand{\footnotesize}{\normalsize}
#+latex_header: \usepackage{morewrites}
#+latex_header: \usepackage{calc,tikz}                         
#+latex_header: \definecolor{ocre}{HTML}{F16723}
#+latex_header: \usepackage{imakeidx}
#+latex_header: \footnotesep\baselineskip
#+latex_header: \setlength{\parskip}{5pt}
#+latex_header: \usepackage{framed}
#+latex_header: \colorlet{shadecolor}{PaleTurquoise} %% use \begin{shaded}
#+latex_header: \usepackage[defaultlines=2,all]{nowidow}
#+latex_header: \sloppy
#+latex_header: \flushbottom
#+latex_header: \usepackage{url}
#+latex_header: \urlstyle{same} %%## 2017/01/30
#+latex_header: \usepackage[useregional,showdow]{datetime2}
#+latex_header: \usepackage{enumitem}
#+latex_header: \setlist{nolistsep}
#+latex_header: \setlist[itemize]{noitemsep}
#+latex_header: \setlist[enumerate]{noitemsep}
#+latex_header: \renewcommand*\glspostdescription{\dotfill} %%## for syn 2017/01/30
#+latex_header: \usepackage{array}
#+latex_header: \usepackage[framemethod=tikz]{mdframed}
#+latex_header: \usetikzlibrary{shadows}
#+latex_header: \definecolor{cccolor}{rgb}{.67,.7,.67}
#+latex_header: \usepackage{tcolorbox}
#+latex_header: \usepackage{float}

#+include: /home/boudiccas/research/header.org
#+latex_header: \usepackage{minitoc}


#+latex_header: \setlength{\parskip}{5pt} % gap between paragraphs
#+latex_header: \setlength{\parsep}{0pt} % space between paragraphs within an item
#+latex_header: \setlength{\topskip}{0pt} % between header and text
#+latex_header: \setlength{\topmargin}{0pt} % gap above header
#+latex_header: \setlength{\topsep}{0pt} % space between first item and preceding paragraph
#+latex_header: \setlength{\partopsep}{0pt} % extra space added to \topsep when environment starts a new paragraph
# # http://www-h.eng.cam.ac.uk/help/tpl/textprocessing/squeeze.html
#+latex_header: \linespread{0.9}
--8<---------------cut here---------------end--------------->8---

This is in an emacs org-mode file which is then exported to latex.
According to the 'hormones18.log' minitoc is being loaded, but in the
projects folder it only shows these files - 'hormones18.maf',
'hormones18.mtc', and 'hormones18.mtc0'.

What do I need please to persuade it to produce all the required
minitocs in the chapters?

Thanks
Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
DrugFacts = https://www.drugfacts.org.uk  
Debian 9.0, fluxbox 1.3.5-2, emacs 25.1.1, org-mode 9.0.7

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[relevance 11%]

* Non-appearance of tables in PDF export under \listoftables
@ 2017-06-26 14:16 10% Sharon Kimble
  0 siblings, 0 replies; 200+ results
From: Sharon Kimble @ 2017-06-26 14:16 UTC (permalink / raw)
  To: org-mode-email

[-- Attachment #1: Type: text/plain, Size: 6210 bytes --]


I'm having great difficulty in getting my tables to show up in
'\listoftables', the 'Table' header shows in my pdf but nothing else
related to tables in the preamble after the TOC.

Taking this table as an example -

--8<---------------cut here---------------start------------->8---
#+LABEL: tab:table1
#+NAME: tab:table1
#+CAPTION: Previous versions of this document
#+ATTR_LATEX: :booktabs t :placement [H]
| *Title*                   | *Version* | *Published*     |
|-------------------------+---------+---------------|
| Hormones 2016           |     1.5 | May 2016      |
| Hormones 2017           |     1.6 |               |
--8<---------------cut here---------------end--------------->8---

Which is exported to latex as this -

--8<---------------cut here---------------start------------->8---
\section{Previous versions}
\label{sec:orgd5daa04}
\begin{table}[H]
\centering
\begin{tabular}{lrl}
\toprule
\textbf{Title} & \textbf{Version} & \textbf{Published}\\
\midrule
Hormones 2016 & 1.5 & May 2016\\
Hormones 2017 & 1.6 & \\
\bottomrule
\end{tabular}
\caption{\label{tab:org2f5a19c}
Previous versions of this document}

\end{table}
--8<---------------cut here---------------end--------------->8---

I am using my own latex-class called 'my-report' which is like this in
my config.org -

--8<---------------cut here---------------start------------->8---
(with-eval-after-load 'ox-latex
(add-to-list 'org-latex-classes
             '("my-report" "\\documentclass{report}
               [NO-DEFAULT-PACKAGES]"
               ;;[EXTRA]"
               ;;("\\part{%s}" . "\\part*{%s}")
               ("\\chapter{%s}" . "\\chapter*{%s}")
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
              ;; (custom-set-variables '(org-export-allow-bind-keywords t))
--8<---------------cut here---------------end--------------->8---

And here is my main preamble -

--8<---------------cut here---------------start------------->8---
#+TITLE: Hormones 2017\\
# #+TITLE: Part 1
#+AUTHOR: Sharon Kimble\\
#+AUTHOR: (S.E.N., R.G.N)\\
#+AUTHOR: redacted
#+DATE: \today \\
#+DATE: Build - 2017.\thevernum
#+STARTUP: fnadjust
#+LaTeX_class: my-report
#+LATEX_CLASS_OPTIONS: [a4paper,11pt,oneside,openany,british,svgnames,dvipsnames]
#+latex_header: \usepackage[a4paper,left=25mm,right=25mm,top=25mm,bottom=30mm,footskip=5mm,headsep=2mm]{geometry}
#+latex_header: \input{/home/boudiccas/research/hormones17/titlepage}
# #+LATEX_CLASS_OPTIONS: [british,svgnames,dvipsnames]
#+latex_header: \usepackage[backend=biber,style=authoryear,doi=true,hyperref=true,backref=true,backrefstyle=two,date=year,maxcitenames=3]{biblatex}
#+LATEX_HEADER: \addbibresource{/home/boudiccas/research/hormones17/hormones17.bib}
#+latex_header: \input{/home/boudiccas/research/codebase}
#+latex_header: \makeindex[title=General Index,options=-s ./index.ist,columnseprule,intoc]
#+latex_header: \makeindex[name=horm,title=Index of Hormones,options=-s ./index.ist,columnseprule,intoc,columns=2]
#+latex_header: \makeindex[name=side,title=Index of Hormones Side-Effects,options=-s ./index.ist,columnseprule,intoc,columns=2]
#+latex_header: \makeindex[name=other,title=Index of Other Drugs Side-Effects,options=-s ./index.ist,columnseprule,intoc,columns=2]
#+latex_header: \makeindex[name=inter,title=Index of Interactions,options=-s ./index.ist,columnseprule,intoc,columns=2]
# #+latex_header: \makeindex[name=sti,title=Index of STI's,options=-s ./index.ist,columnseprule,intoc,columns=2]

#+latex_header: \usepackage{hyperref}
#+latex_header: \hypersetup{linktoc=all,colorlinks,linkcolor={red},citecolor={magenta},urlcolor={blue}}
# #+latex_header: \hypersetup{linktoc=all,colorlinks,linkcolor={black},citecolor={black},urlcolor={black}}
#+latex_header: \usepackage[toc,nopostdot,style=listgroup]{glossaries}
#+latex_header: \input{hormones17.glos}
#+latex_header: \makeglossaries
#+latex_header: \glsenablehyper
#+latex_header: \renewcommand{\glstextformat}[1]{\underline{\color{red}\em #1}}
#+latex_header: \usepackage{todo}
#+latex_header: \usepackage[firstpage]{draftwatermark}
#+LaTeX_header: \setcounter{secnumdepth}{0}
#+latex_header: \setcounter{tocdepth}{1}
#+latex_header: \usepackage{everypage}
#+latex_header: \usepackage{booktabs}
#+include: /home/boudiccas/research/header.org
#+latex_header: \usepackage{textgreek}
#+latex_header: \usepackage{pifont}
#+latex_header: \usepackage{upgreek}
#+latex_header: \usepackage{longtable}


#+latex_header: \setlength{\parskip}{5pt} % gap between paragraphs
#+latex_header: \setlength{\parsep}{0pt} % space between paragraphs within an item
# #+latex_header: \setlength{\headsep}{5pt} % the vertical length between the header and the top of the text area
#+latex_header: \setlength{\topskip}{0pt} % between header and text
#+latex_header: \setlength{\topmargin}{0pt} % gap above header
#+latex_header: \setlength{\topsep}{0pt} % space between first item and preceding paragraph
#+latex_header: \setlength{\partopsep}{0pt} % extra space added to \topsep when environment starts a new paragraph
# http://www-h.eng.cam.ac.uk/help/tpl/textprocessing/squeeze.html
#+latex_header: \linespread{0.9}

# #+OPTIONS: H:6 \n:nil ::t |:t ^:t f:t tex:t
#+OPTIONS: H:7 toc:t \n:nil ::t |:t ^:t f:t tex:t
# #+LaTeX_header: \setcounter{secnumdepth}{0}
# #+OPTIONS: toc:1


# #+LATEX: \tableofcontents
# #+LATEX: \listoftables
# #+LATEX: \listoffigures

#+TOC: tables

\dominitoc
--8<---------------cut here---------------end--------------->8---

Can anyone please help me to get '\listoftables' working please, I just
feel like I'm going round in circles at the moment and not achieving
anything, and its so frustrating

Thanks
Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
DrugFacts = https://www.drugfacts.org.uk  
Debian 9.0, fluxbox 1.3.5-2, emacs 25.1.1, org-mode 9.0.7

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[relevance 10%]

* Fwd: Re: How to export LaTeX amsmath align bmatrix to ODT?
       [not found]           ` <3c4faaee17eb7e7fdd5aea5136742bd5@openmail.cc>
@ 2017-06-25  0:35  5%         ` edgar
  0 siblings, 0 replies; 200+ results
From: edgar @ 2017-06-25  0:35 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 4805 bytes --]

I forgot to send this to the list. Sorry.

-------- Original Message --------
Subject: Re: How to export LaTeX amsmath align bmatrix to ODT?
Date: 2017-06-15 22:57
 From: edgar@openmail.cc
To: Nicolas Goaziou <mail@nicolasgoaziou.fr>

Hello Nicolas,

Thank you for your help. My comments are under each block:

On 2017-06-14 14:10, Nicolas Goaziou wrote:
> Hello,
> 
> 
>> On 2017-06-10 05:13, edgar wrote:
>>> On 2017-06-10 04:54, edgar wrote:
>>>> Hello,
>>>> 
>>>> I have been making progress with my export procedure to ODT. I would
>>>> like to know if someone knows how to export the following LaTeX 
>>>> block
>>>> to ODT correctly:
>>>> 
>>>> \[\begin{align} \begin{bmatrix} a = 1 & b=2 \\ c=3 & d = 4
>>>> \end{bmatrix} \end{align}\]
>>>> https://www.vfemail.net/roundcube/?_task=mail&_action=compose&_id=289067995593b7fd683a1f#
>>>> \[\begin{align}  a = & 1 + 2 + 3 + 4 \\ c = &  4 \end{bmatrix}
>>>> \end{align}\]
> 
> I'm a bit lost here. In particular, I'm able to export the example 
> above
> out-of-the-box, provided I add "#+options: tex:dvipng" or some such in
> the document.
> 

Yes, indeed, without modifying any variable, the code exports correctly, 
but I had modified org-preview-latex-process-alist to include my 
symbols.tex file like this:

On 2017-06-05 07:00, edgar wrote:

     I managed to get the special symbols by

     1. M-x customize-variable org-preview-latex-process-alist
     2. Doing [Ins] into the dvipng (or imagemagick) section
     3. typing :latex-header in the Key: field
     4. typing "\\input{./symbols.tex}" in the Value: field

After I did that, some symbols would export correctly, but others would 
not. I was not importing any LaTeX packages within that file. I use this 
file to export PDF (through LaTeX: C-c C-e l p). One of the things that 
did not work was the matrix environment. I thought that it was better to 
start a new question regarding the matrix, because I thought it was 
independent of the symbols.

This is related to the following:

>> For the record, I had modified org-preview-latex-process-alist to get
>> custom symbols, and this got in the way of the LaTeX bmatrix
>> environment (I don't know how; I was loading a file with
>> with :latex-header as "\\input{preamble.tex}").
>> 
>> My partial answer (it is partial, because the \tensor preview renders
>> in a different color than the rest of symbols): Instead of modifying
>> org-preview-latex-process-alist, the answer I modified
>> org-format-tex-header. I added the following at the end of M-x
>> customize-variable org-format-tex-header (I leave it here for
>> posterity; I added some symbols: tensor, derivative, vector, Roman
>> numeral, etc.)
> 
> I don't think you need to modify `org-format-latex-header' at all. 
> There
> is `org-latex-packages-alist' for that.
I don't really know how to modify org-latex-packages-alist to have a 
latex command like this in my tex file:

\newcommmand{\mysymbol}[1]{\mathrm{my_{#1}}}

I do have a bunch of packages with custom options over there :P !

> 
> So, is there a bug in the ODT export back-end? If so, could you post an
> ECM? Loads of LaTeX code doesn't help understanding the issue.
> 
I think that the only bug is that I don't know how to use it very well 
;) . I don't know what a ECM is :S , sorry. I typed ECM emacs on a web 
search engine, and only got ECB. Is it the same? If you are willing to 
tell me how to get one, I'll do my best.

Right now, I am having a glitch on the screen. I get some of my custom 
symbols in black (all the others are in light gray) on a black 
background (my screen has a black background; see attached picture: 
there is an I with two tildes underneath next to the p). I would like to 
know if you or someone else can help me to get a light gray on that 
symbol too. I suspect that it may have to do with the stackengine 
(LaTeX) package, because all of my other symbols are doing well. This is 
the snippet of code that I have in org-format-latex-header to define the 
\tensor symbol

\newcommand{\tensor}[1]{
   
\stackunder[0pt]{\stackunder[1pt]{#1}{\scriptscriptstyle\sim}}{\scriptscriptstyle\sim}}

I also opened a new emacs with -Q, did a (require 'org), yanked my 
configuration of org-format-latex-header and created a new Org file. 
Then, changed the theme to a dark one and I typed $\tensor{F}$ $a$. For 
the $\tensor{F}$ I get a white square with a black font face. For the 
$a$ I get the same set of colors as the theme (dark background, 
light-gray font face).

Thank you a lot for you time!


Edgar

-------------------------------------------------

ONLY AT VFEmail! - Use our Metadata Mitigator to keep your email out of the NSA's hands!
$24.95 ONETIME Lifetime accounts with Privacy Features!  
15GB disk! No bandwidth quotas!
Commercial and Bulk Mail Options!  

[-- Attachment #2: org-ltximg_968041b7b2f6ea14aa6a6df6b779409cb85988b9.png --]
[-- Type: application/octet-stream, Size: 368 bytes --]

^ permalink raw reply	[relevance 5%]

* Re: How to export LaTeX amsmath align bmatrix to ODT?
  @ 2017-06-12 21:36 11%   ` edgar
    0 siblings, 1 reply; 200+ results
From: edgar @ 2017-06-12 21:36 UTC (permalink / raw)
  To: emacs-orgmode

On 2017-06-10 05:13, edgar@openmail.cc wrote:
> On 2017-06-10 04:54, edgar@openmail.cc wrote:
>> Hello,
>> 
>> I have been making progress with my export procedure to ODT. I would
>> like to know if someone knows how to export the following LaTeX block
>> to ODT correctly:
>> 
>> \[\begin{align} \begin{bmatrix} a = 1 & b=2 \\ c=3 & d = 4
>> \end{bmatrix} \end{align}\]
>> https://www.vfemail.net/roundcube/?_task=mail&_action=compose&_id=289067995593b7fd683a1f#
>> \[\begin{align}  a = & 1 + 2 + 3 + 4 \\ c = &  4 \end{bmatrix} 
>> \end{align}\]
>> 
>> As always, any help is welcome :) .
>> 
>> 
>> Edgar
> 
> By the way, I tried with latexmlmath and mathtoweb.jar without success.

Ok. I got it (with a minor glitch). If someone can help me to get the 
right colors on the screen (my screen is black; the \tensor symbol is 
also black), I would appreciate it. Now I can export to ODT with my 
custom symbols and the bmatrix environment.

For the record, I had modified org-preview-latex-process-alist to get 
custom symbols, and this got in the way of the LaTeX bmatrix environment 
(I don't know how; I was loading a file with with :latex-header as 
"\\input{preamble.tex}").

My partial answer (it is partial, because the \tensor preview renders in 
a different color than the rest of symbols): Instead of modifying 
org-preview-latex-process-alist, the answer I modified 
org-format-tex-header. I added the following at the end of M-x 
customize-variable org-format-tex-header (I leave it here for posterity; 
I added some symbols: tensor, derivative, vector, Roman numeral, etc.)

\usepackage{stackengine}
\stackMath
% Does not work
% \newcommand\tenq[2]{%
% \def\useanchorwidth{T}%
%  \ifnum#1>1%
%    
\stackunder[0pt]{\tenq[\numexpr#1-1\relax]{#2}}{\scriptscriptstyle\sim}%
%  \else%
%    \stackunder[1pt]{#2}{\scriptscriptstyle\sim}%
%  \fi%
%}

% Change del operator to d
% 
http://tex.stackexchange.com/questions/178946/better-automatic-spacing-of-differential-d
\renewcommand{\d}[1]{\mathop{\mathrm{d}{#1}}\!{}}
\newcommand{\del}[1]{\d{\left(#1\right)}}
\newcommand{\diff}[2]{
   \frac{\d{}}{\d{#2}}
   \left(#1\right)}
\newcommand{\deriv}[2]{
   \frac{\del{#1}}{\d{#2}}}

% https://tex.stackexchange.com/a/229547
\renewcommand{\vec}[1]{
   \hbox{\oalign{$#1$\crcr\hidewidth$\scriptscriptstyle\sim$\hidewidth}}}
% --- Define \dvec and \ddvec for dotted and double-dotted vectors.
\newcommand{\dvec}[1]{\dot{\vec{#1}}}
\newcommand{\ddvec}[1]{\ddot{\vec{#1}}}

% 
https://tex.stackexchange.com/questions/229543/double-tilde-symbol-under-letter
\newcommand{\dtens}[1]{
   
\stackunder[0pt]{\stackunder[1pt]{#1}{\scriptscriptstyle\sim}}{\scriptscriptstyle\sim}}

\newcommand{\ftens}[1]{
   
\stackunder[0pt]{\stackunder[0pt]{\stackunder[0pt]{\stackunder[1pt]{#1}{\scriptscriptstyle\sim}}{\scriptscriptstyle\sim}}{\scriptscriptstyle\sim}}{\scriptscriptstyle\sim}
}

% Define \tensor and \mtensor (matrix)
\newcommand{\tensor}[1]{\dtens{#1}}
\newcommand{\tens}[1]{\ftens{#1}}

\newcommand{\mtensor}[1]{%
   \left[{\tensor{#1}}\right]}
% --- Define \dtens and \ddtens for dotted and double-dotted tensors.
\newcommand{\dtens}[1]{\dot{\tensor{#1}}}
\newcommand{\ddtens}[1]{\ddot{\tensor{#1}}}
% --- Define \dmtens and \ddmtens for dotted and double-dotted tensors.
\newcommand{\dmtens}[1]{\dot{\mtensor{#1}}}
\newcommand{\ddmtens}[1]{\ddot{\mtensor{#1}}}

% Trace
\newcommand{\Tr}[1]{\mathop{\mathrm{tr}}\!{}\left(#1\right)}

% Have a thicker line for the mean value
%\newcommand*{\mean}[1]{\overbracket[0.65pt][-1pt]{#1}}
% amssymb, amsmath
% adapt: 
http://tex.stackexchange.com/questions/22100/the-bar-and-overline-commands
\newcommand{\mean}[1]{\mkern 
3mu\overbracket[0.65pt][-1pt]{\mkern-3mu#1\mkern-3mu}\mkern 3mu}

% Roman number III
\def\III{I\hspace{-2pt}I\hspace{-2pt}I}

-------------------------------------------------

ONLY AT VFEmail! - Use our Metadata Mitigator to keep your email out of the NSA's hands!
$24.95 ONETIME Lifetime accounts with Privacy Features!  
15GB disk! No bandwidth quotas!
Commercial and Bulk Mail Options!  

^ permalink raw reply	[relevance 11%]

* Re: Making DocBook xml books from org mode?
  2016-09-29 18:04  9% Making DocBook xml books from org mode? Peter Davis
@ 2016-09-29 19:23  0% ` Joost Kremers
  0 siblings, 0 replies; 200+ results
From: Joost Kremers @ 2016-09-29 19:23 UTC (permalink / raw)
  To: Peter Davis; +Cc: emacs-orgmode


On Thu, Sep 29 2016, Peter Davis wrote:
> I've started a new position in which I have to create and maintain a
> large set of documents in DocBook xml format. For new books, I'd really
> like to use org mode, since a) I'm already familiar with it, b) I love
> it, and c) I believe it does (or can be made to do) nearly everything I
> need.
>
> However, after Googling around the org-mode/DocBook space, I'm left with
> some questions.
>
> 1. I'm going to be creating books, as opposed to articles. My org-header
> looks like this:
>
> #+STARTUP: showeverything logdone
> #+OPTIONS:   H:5 num:t \n:nil @:t ::t |:t ^:nil -:t f:t *:t <:t
> #+LaTeX_CLASS: koma-article
> #+LaTeX_HEADER: \usepackage{listings}
> #+LATEX_HEADER: \setlength{\parskip}{2ex plus 4pt minus 2pt}
> #+LATEX_HEADER: \setlength{\parindent}{0pt}
> #+LATEX_HEADER: \renewcommand{\baselinestretch}{1.0}
> #+LATEX_HEADER: \setlength{\topsep}{-10pt}
> #+LATEX_HEADER: \setlength{\partopsep}{0pt}
> #+LaTeX_HEADER: \usepackage{xcolor}
> #+LaTeX_HEADER: \lstset{
> #+LaTeX_HEADER:     basicstyle=\ttfamily,
> #+LaTeX_HEADER:     breaklines=true,
> #+LaTeX_HEADER:
> prebreak=\mbox{\ensuremath{\color{red}\hookleftarrow}},
> #+LaTeX_HEADER:
> postbreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\color{red}\hookrightarrow\space}},
> #+LaTeX_HEADER:     columns=fullflexible,
> #+LaTeX_HEADER:     keepspaces=true
> #+LaTeX_HEADER: }
> #+LaTeX_CLASS_OPTIONS:
> [book,letterpaper,times,12pt,listings-bw,microtype]
>
>     but the PDFs I'm getting still look like articles. (I copied the
>     above from some examples posted on this list a while ago. Thanks!)

Your LaTeX_CLASS is set to `koma-article', so that makes sense.

>  2. Are there any advantages to considering MarkDown or AsciiDoc as
>  opposed to org markup? (Again, my familiarity with org is a strong
>  incentive here, but I'm willing to consider other options.)

There is a (IMHO) excellent markdown-mode available on Melpa, and if you
use Pandoc[1] to convert your documents you have a lot of flexibility.
There's also `pandoc-mode' (of which I'm the author), a minor mode that
makes interacting with pandoc from within Emacs easier.

>  3. The direct route from org to DocBook xml seems to be missing. From
>  what I gather, I can get there somehow via texi (but I don't even have
>  that in org currently), or perhaps export to HTML and then convert that
>  to db xml. Am I missing something? Is there some other route I should
>  consider?

Pandoc can convert to Docbook, so that might be an option. Note that
Pandoc also converts *from* Org, (although it cannot handle all of Org's
capabilities), so depending on your needs, that might be a way to go
directly from Org to Docbook.

>  4. [LONGSHOT] Is there any way to /import/ docbook xml into org mode?

Pandoc also converts *from* Docbook, and can convert *to* Org, so again,
that might be of help.

Of course, whether Pandoc can be useful to you really depends on your
needs. Pandoc's internal document representation is based on Markdown,
and by its very nature Markdown is more limited in it capabilities than
Org. In essence, anything that cannot be handled by (Pandoc's version
of) Markdown, cannot be handled by Pandoc in other formats.

HTH

--
Joost Kremers
Life has its moments

^ permalink raw reply	[relevance 0%]

* Making DocBook xml books from org mode?
@ 2016-09-29 18:04  9% Peter Davis
  2016-09-29 19:23  0% ` Joost Kremers
  0 siblings, 1 reply; 200+ results
From: Peter Davis @ 2016-09-29 18:04 UTC (permalink / raw)
  To: emacs-orgmode

I've started a new position in which I have to create and maintain a
large set of documents in DocBook xml format. For new books, I'd really
like to use org mode, since a) I'm already familiar with it, b) I love
it, and c) I believe it does (or can be made to do) nearly everything I
need.

However, after Googling around the org-mode/DocBook space, I'm left with
some questions.

1. I'm going to be creating books, as opposed to articles. My org-header
looks like this:

#+STARTUP: showeverything logdone
#+OPTIONS:   H:5 num:t \n:nil @:t ::t |:t ^:nil -:t f:t *:t <:t
#+LaTeX_CLASS: koma-article
#+LaTeX_HEADER: \usepackage{listings}
#+LATEX_HEADER: \setlength{\parskip}{2ex plus 4pt minus 2pt}
#+LATEX_HEADER: \setlength{\parindent}{0pt}
#+LATEX_HEADER: \renewcommand{\baselinestretch}{1.0}
#+LATEX_HEADER: \setlength{\topsep}{-10pt}
#+LATEX_HEADER: \setlength{\partopsep}{0pt}
#+LaTeX_HEADER: \usepackage{xcolor}
#+LaTeX_HEADER: \lstset{
#+LaTeX_HEADER:     basicstyle=\ttfamily,
#+LaTeX_HEADER:     breaklines=true,
#+LaTeX_HEADER:    
prebreak=\mbox{\ensuremath{\color{red}\hookleftarrow}},
#+LaTeX_HEADER:    
postbreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\color{red}\hookrightarrow\space}},
#+LaTeX_HEADER:     columns=fullflexible,
#+LaTeX_HEADER:     keepspaces=true
#+LaTeX_HEADER: }
#+LaTeX_CLASS_OPTIONS:
[book,letterpaper,times,12pt,listings-bw,microtype]

    but the PDFs I'm getting still look like articles. (I copied the
    above from some examples posted on this list a while ago. Thanks!)

 2. Are there any advantages to considering MarkDown or AsciiDoc as
 opposed to org markup? (Again, my familiarity with org is a strong
 incentive here, but I'm willing to consider other options.)

 3. The direct route from org to DocBook xml seems to be missing. From
 what I gather, I can get there somehow via texi (but I don't even have
 that in org currently), or perhaps export to HTML and then convert that
 to db xml. Am I missing something? Is there some other route I should
 consider?

 4. [LONGSHOT] Is there any way to /import/ docbook xml into org mode?

Thank you very much.

-pd

-- 
  Peter Davis
  www.techcurmudgeon.com

^ permalink raw reply	[relevance 9%]

* Re: page-numbering in a toc
  2016-08-17  9:46  8% page-numbering in a toc Sharon Kimble
@ 2016-08-17 17:39  0% ` Sharon Kimble
  0 siblings, 0 replies; 200+ results
From: Sharon Kimble @ 2016-08-17 17:39 UTC (permalink / raw)
  To: org-mode-email

[-- Attachment #1: Type: text/plain, Size: 7190 bytes --]

Sharon Kimble <boudiccas@skimble.plus.com> writes:

> I'm having great difficulties with my toc, every toc item, except for
> the chapter only allows me to get to the chapter toc entry. For instance
> the chapter toc entry might be on page 216, but a section heading entry
> on page 225 only allows you to get to page 216. I've tried various
> things but its still defaulting to it.
>
> How can I correct it please?

I've solved this by removing the 'titlesec' and 'sectsty' packages,
which are incompatible with each other anyway. But any instance of
'titlesec' provokes the problems that I've outlined, but on total
removal of it then everything works perfectly.

Sharon.

>
> Here is my preamble except for the title/author/date which don't seem
> relevant. I would provide a MWE but its too awkward due to the length of
> the document.
>
> #+STARTUP: fnadjust
> #+LaTeX_class: my-report
> #+latex_header: \input{/home/boudiccas/research/aging/dementia/titlepage}
> #+LATEX_CLASS_OPTIONS: [a4paper,12pt,oneside,openany,british,svgnames,dvipsnames]
> # #+LATEX_HEADER_EXTRA: \usepackage{lmodern}
> # #+latex_header: \usepackage[mark]{gitinfo2}
> # #+LaTeX_HEADER: \usepackage{libertine}
> #+latex_header: \usepackage[backend=biber,style=authoryear,doi=true,hyperref=true,backref=true,backrefstyle=two,date=year,maxcitenames=3]{biblatex}
> #+LATEX_HEADER: \addbibresource{~/research/age-and-trans/dementia/dementia.bib}
> #+latex_header: \input{/home/boudiccas/research/codebase}
> #+latex_header: \makeindex[title=Index,options=-s ./index.ist,columnseprule,intoc]
> #+latex_header: \makeindex[name=symp,title=Index of Symptoms,options=-s ./index.ist,columnseprule,intoc]
> #+latex_header: \makeindex[name=se,title=Index of Side-effects,options=-s ./index.ist,columnseprule,intoc]
> #+latex_header: \makeindex[name=risk,title=Index of Risk Factors,options=-s ./index.ist,columnseprule,intoc]
> # #+latex_header: \makeindex[name=test,title=Index of Tests and Scans,options=-s ./index.ist,columnseprule,intoc]
> #+latex_header: \makeindex[name=drug,title=Index of Medicinal Drugs,options=-s ./index.ist,columnseprule,intoc]
> #+latex_header: \usepackage{hyperref}
> #+latex_header: \hypersetup{linktoc=all,colorlinks,linkcolor={red},citecolor={magenta},urlcolor={blue}}
> #+latex_header: \usepackage[acronym,toc,nopostdot,style=listgroup]{glossaries}
> #+latex_header: \input{dementia.glos}
> #+latex_header: \makeglossaries
> #+latex_header: \glsenablehyper
> #+latex_header: \usepackage{todo}
> #+latex_header: \usepackage{draftwatermark}
> #+latex_header: \usepackage{everypage}
> # #+LaTeX_header: \setcounter{secnumdepth}{7}
> #+LaTeX_header: \setcounter{secnumdepth}{0}
> #+latex_header: \setcounter{tocdepth}{1}
> #+latex_header: \footnotesep\baselineskip
> #+latex_header: \setlength{\parskip}{5pt}
> #+OPTIONS: H:6 toc:t \n:nil ::t |:t ^:t f:t tex:t
> # #+latex_header: \renewcommand{\thesection}{}
> # #+include: /home/boudiccas/research/header.org
> #+LATEX_HEADER: \usepackage{float,booktabs}
> # #+LATEX_HEADER: \usepackage{adjustbox} 
> # #+LATEX_HEADER_EXTRA: \usepackage{rotfloat}
>
> #+latex_header: \usepackage[mark]{gitinfo2}
> # #+LaTeX_HEADER: \usepackage{mathpazo,upgreek,pifont,microtype}
> #+LaTeX_HEADER: \usepackage{libertine}
> # #+LaTeX_HEADER: \usepackage{lmodern}
>
> # #+LATEX_HEADER: \addbibresource{/home/boudiccas/research/aging/cancer/cancer.bib}
> # #+latex_header: \input{/home/boudiccas/research/codebase}
> #+latex_header: \usepackage{bookmark}
>
> # #+latex_header: \makeglossaries
> # #+latex_header: \glsenablehyper
> #+latex_header: \usepackage{color,soul,xcolor}
> # #+latex_header: \definecolor{lightblue}{rgb}{.90,.95,1}
> # #+latex_header: \sethlcolor{lightblue}
> #+latex_header: \newcommand\reduline{\bgroup\markoverwith{\textcolor{red}{\rule[-0.75ex]{2pt}{1.5pt}}}\ULon}
> #+latex_header: \usepackage{sectsty}
> # #+latex_header: \subsectionfont{\normalfont\itshape}
> # #+latex_header: \subsubsectionfont{\normalfont\bfseries\itshape\underline}
> #+latex_header: \subsubsectionfont{\normalfont\bfseries\itshape}
> # #+latex_header: \subsectionfont{\normalfont\bfseries\itshape}
> #+latex_header: \usepackage{caption}
> # #+latex_header: \setlength\parindent{0pt} % sets indent to zero
> # #+latex_header: \usepackage{hyperref}
> # #+latex_header: \hypersetup{linktoc=all,colorlinks,linkcolor={red},citecolor={magenta},urlcolor={blue}}
> #+latex_header: \setlength\parindent{0pt} % sets indent to zero
> #+latex_header: \usepackage{chngcntr}
> #+latex_header: \counterwithout{footnote}{chapter}
> #+latex_header: \usepackage[Lenny]{fncychap}
> #+latex_header: \usepackage[toc]{multitoc}
> # #+latex_header: \usepackage{minitoc}
> # #+latex_header: \usepackage[font=footnotesize]{idxlayout}
> # #+latex_header: \usepackage{idxlayout}
> #+latex_header: \usepackage{morewrites}
> #+latex_header: \usepackage{calc,tikz}                         
> #+latex_header: \definecolor{ocre}{HTML}{F16723}
> #+latex_header: \usepackage{imakeidx}
> # #+latex_header: \usepackage[makeindex]{splitidx}
> # #+latex_header: \makeindex[title=Index,options=-s ./index.ist,columnseprule,intoc]
> # #+latex_header: \makeindex[name=symp,title=Index of Symptoms,options=-s ./index.ist,columnseprule,intoc]
> # #+latex_header: \makeindex[name=se,title=Index of Side-effects,options=-s ./index.ist,columnseprule,intoc]
> # #+latex_header: \renewcommand{\listtablename}{Tables}
> # #+latex_header: \newenvironment{bluefont}{\fontfamily{libertine}\selectfont\textcolor{blue}}{\par}
> # #+latex_header: \usepackage[export]{adjustbox}
> # #+latex_header: \footmarkstyle{#1.\,}
> #+latex_header: \footnotesep\baselineskip
> #+latex_header: \setlength{\parskip}{5pt}
> # #+OPTIONS: H:7 toc:t \n:nil ::t |:t ^:t f:t tex:t #test
> # #+LaTeX_header: \setcounter{secnumdepth}{0}
> # #+OPTIONS: toc:1
> # #+latex_header: \input{cancer.glos}
> #+latex_header: \renewcommand*\glspostdescription{\dotfill}
> #+latex_header: \usepackage{framed}
> # #+latex_header: \colorlet{shadecolor}{PaleTurquoise} %% use \begin{shaded}
> #+latex_header: \usepackage[defaultlines=2,all]{nowidow}
> #+latex_header: \sloppy
> #+latex_header: \flushbottom
> #+latex_header: \usepackage{url}
> #+latex_header: \urlstyle{same}
> #+latex_header: \usepackage[useregional,showdow]{datetime2}
> #+latex_header: \usepackage{enumitem}
> #+latex_header: \setlist{nolistsep}
> #+latex_header: \setlist[itemize]{noitemsep}
> #+latex_header: \setlist[enumerate]{noitemsep}
> #+latex_header: \renewcommand*\glspostdescription{\dotfill}
> #+latex_header: \usepackage{array}
> #+latex_header: \usepackage[framemethod=tikz]{mdframed}
> #+latex_header: \usetikzlibrary{shadows}
> #+latex_header: \definecolor{cccolor}{rgb}{.67,.7,.67}
> #+latex_header: \usepackage{tcolorbox}
> #+latex_header: \newcommand{\breakingspace}[1]{#1\hspace{0pt}}
> #+latex_header: \usepackage{morewrites}
> #+latex_header: \usepackage[compact]{titlesec}
>
> Thanks
> Sharon.

-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
Debian 8.4, fluxbox 1.3.7, emacs 25.1.1

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[relevance 0%]

* page-numbering in a toc
@ 2016-08-17  9:46  8% Sharon Kimble
  2016-08-17 17:39  0% ` Sharon Kimble
  0 siblings, 1 reply; 200+ results
From: Sharon Kimble @ 2016-08-17  9:46 UTC (permalink / raw)
  To: org-mode-email

[-- Attachment #1: Type: text/plain, Size: 6762 bytes --]


I'm having great difficulties with my toc, every toc item, except for
the chapter only allows me to get to the chapter toc entry. For instance
the chapter toc entry might be on page 216, but a section heading entry
on page 225 only allows you to get to page 216. I've tried various
things but its still defaulting to it.

How can I correct it please?

Here is my preamble except for the title/author/date which don't seem
relevant. I would provide a MWE but its too awkward due to the length of
the document.

--8<---------------cut here---------------start------------->8---
#+STARTUP: fnadjust
#+LaTeX_class: my-report
#+latex_header: \input{/home/boudiccas/research/aging/dementia/titlepage}
#+LATEX_CLASS_OPTIONS: [a4paper,12pt,oneside,openany,british,svgnames,dvipsnames]
# #+LATEX_HEADER_EXTRA: \usepackage{lmodern}
# #+latex_header: \usepackage[mark]{gitinfo2}
# #+LaTeX_HEADER: \usepackage{libertine}
#+latex_header: \usepackage[backend=biber,style=authoryear,doi=true,hyperref=true,backref=true,backrefstyle=two,date=year,maxcitenames=3]{biblatex}
#+LATEX_HEADER: \addbibresource{~/research/age-and-trans/dementia/dementia.bib}
#+latex_header: \input{/home/boudiccas/research/codebase}
#+latex_header: \makeindex[title=Index,options=-s ./index.ist,columnseprule,intoc]
#+latex_header: \makeindex[name=symp,title=Index of Symptoms,options=-s ./index.ist,columnseprule,intoc]
#+latex_header: \makeindex[name=se,title=Index of Side-effects,options=-s ./index.ist,columnseprule,intoc]
#+latex_header: \makeindex[name=risk,title=Index of Risk Factors,options=-s ./index.ist,columnseprule,intoc]
# #+latex_header: \makeindex[name=test,title=Index of Tests and Scans,options=-s ./index.ist,columnseprule,intoc]
#+latex_header: \makeindex[name=drug,title=Index of Medicinal Drugs,options=-s ./index.ist,columnseprule,intoc]
#+latex_header: \usepackage{hyperref}
#+latex_header: \hypersetup{linktoc=all,colorlinks,linkcolor={red},citecolor={magenta},urlcolor={blue}}
#+latex_header: \usepackage[acronym,toc,nopostdot,style=listgroup]{glossaries}
#+latex_header: \input{dementia.glos}
#+latex_header: \makeglossaries
#+latex_header: \glsenablehyper
#+latex_header: \usepackage{todo}
#+latex_header: \usepackage{draftwatermark}
#+latex_header: \usepackage{everypage}
# #+LaTeX_header: \setcounter{secnumdepth}{7}
#+LaTeX_header: \setcounter{secnumdepth}{0}
#+latex_header: \setcounter{tocdepth}{1}
#+latex_header: \footnotesep\baselineskip
#+latex_header: \setlength{\parskip}{5pt}
#+OPTIONS: H:6 toc:t \n:nil ::t |:t ^:t f:t tex:t
# #+latex_header: \renewcommand{\thesection}{}
# #+include: /home/boudiccas/research/header.org
#+LATEX_HEADER: \usepackage{float,booktabs}
# #+LATEX_HEADER: \usepackage{adjustbox} 
# #+LATEX_HEADER_EXTRA: \usepackage{rotfloat}

#+latex_header: \usepackage[mark]{gitinfo2}
# #+LaTeX_HEADER: \usepackage{mathpazo,upgreek,pifont,microtype}
#+LaTeX_HEADER: \usepackage{libertine}
# #+LaTeX_HEADER: \usepackage{lmodern}

# #+LATEX_HEADER: \addbibresource{/home/boudiccas/research/aging/cancer/cancer.bib}
# #+latex_header: \input{/home/boudiccas/research/codebase}
#+latex_header: \usepackage{bookmark}

# #+latex_header: \makeglossaries
# #+latex_header: \glsenablehyper
#+latex_header: \usepackage{color,soul,xcolor}
# #+latex_header: \definecolor{lightblue}{rgb}{.90,.95,1}
# #+latex_header: \sethlcolor{lightblue}
#+latex_header: \newcommand\reduline{\bgroup\markoverwith{\textcolor{red}{\rule[-0.75ex]{2pt}{1.5pt}}}\ULon}
#+latex_header: \usepackage{sectsty}
# #+latex_header: \subsectionfont{\normalfont\itshape}
# #+latex_header: \subsubsectionfont{\normalfont\bfseries\itshape\underline}
#+latex_header: \subsubsectionfont{\normalfont\bfseries\itshape}
# #+latex_header: \subsectionfont{\normalfont\bfseries\itshape}
#+latex_header: \usepackage{caption}
# #+latex_header: \setlength\parindent{0pt} % sets indent to zero
# #+latex_header: \usepackage{hyperref}
# #+latex_header: \hypersetup{linktoc=all,colorlinks,linkcolor={red},citecolor={magenta},urlcolor={blue}}
#+latex_header: \setlength\parindent{0pt} % sets indent to zero
#+latex_header: \usepackage{chngcntr}
#+latex_header: \counterwithout{footnote}{chapter}
#+latex_header: \usepackage[Lenny]{fncychap}
#+latex_header: \usepackage[toc]{multitoc}
# #+latex_header: \usepackage{minitoc}
# #+latex_header: \usepackage[font=footnotesize]{idxlayout}
# #+latex_header: \usepackage{idxlayout}
#+latex_header: \usepackage{morewrites}
#+latex_header: \usepackage{calc,tikz}                         
#+latex_header: \definecolor{ocre}{HTML}{F16723}
#+latex_header: \usepackage{imakeidx}
# #+latex_header: \usepackage[makeindex]{splitidx}
# #+latex_header: \makeindex[title=Index,options=-s ./index.ist,columnseprule,intoc]
# #+latex_header: \makeindex[name=symp,title=Index of Symptoms,options=-s ./index.ist,columnseprule,intoc]
# #+latex_header: \makeindex[name=se,title=Index of Side-effects,options=-s ./index.ist,columnseprule,intoc]
# #+latex_header: \renewcommand{\listtablename}{Tables}
# #+latex_header: \newenvironment{bluefont}{\fontfamily{libertine}\selectfont\textcolor{blue}}{\par}
# #+latex_header: \usepackage[export]{adjustbox}
# #+latex_header: \footmarkstyle{#1.\,}
#+latex_header: \footnotesep\baselineskip
#+latex_header: \setlength{\parskip}{5pt}
# #+OPTIONS: H:7 toc:t \n:nil ::t |:t ^:t f:t tex:t #test
# #+LaTeX_header: \setcounter{secnumdepth}{0}
# #+OPTIONS: toc:1
# #+latex_header: \input{cancer.glos}
#+latex_header: \renewcommand*\glspostdescription{\dotfill}
#+latex_header: \usepackage{framed}
# #+latex_header: \colorlet{shadecolor}{PaleTurquoise} %% use \begin{shaded}
#+latex_header: \usepackage[defaultlines=2,all]{nowidow}
#+latex_header: \sloppy
#+latex_header: \flushbottom
#+latex_header: \usepackage{url}
#+latex_header: \urlstyle{same}
#+latex_header: \usepackage[useregional,showdow]{datetime2}
#+latex_header: \usepackage{enumitem}
#+latex_header: \setlist{nolistsep}
#+latex_header: \setlist[itemize]{noitemsep}
#+latex_header: \setlist[enumerate]{noitemsep}
#+latex_header: \renewcommand*\glspostdescription{\dotfill}
#+latex_header: \usepackage{array}
#+latex_header: \usepackage[framemethod=tikz]{mdframed}
#+latex_header: \usetikzlibrary{shadows}
#+latex_header: \definecolor{cccolor}{rgb}{.67,.7,.67}
#+latex_header: \usepackage{tcolorbox}
#+latex_header: \newcommand{\breakingspace}[1]{#1\hspace{0pt}}
#+latex_header: \usepackage{morewrites}
#+latex_header: \usepackage[compact]{titlesec}
--8<---------------cut here---------------end--------------->8---

Thanks
Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
Debian 8.4, fluxbox 1.3.7, emacs 25.1.1

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[relevance 8%]

* exporting to subsubsection not completing
@ 2016-04-16 13:21  6% Sharon Kimble
  0 siblings, 0 replies; 200+ results
From: Sharon Kimble @ 2016-04-16 13:21 UTC (permalink / raw)
  To: org-mode-email

[-- Attachment #1: Type: text/plain, Size: 2716 bytes --]

I'm using a custom class for my org-mode latex file which is -

--8<---------------cut here---------------start------------->8---
#+begin_src emacs-lisp
(add-to-list 'org-latex-classes
             '("my-memoir"
               "\\documentclass{memoir}"
               ("\\chapter{%s}" . "\\chapter*{%s}")
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
#+end_src
[2016-04-16 Sat 08:22]
--8<---------------cut here---------------end--------------->8---

but all my subsubsections are coming out as -

╭────
│\begin{enumerate}
│\item Stop the abuse!
╰────

This is my file header, minus the title which isn't relevant

--8<---------------cut here---------------start------------->8---
#+LaTeX_class: my-memoir
#+LATEX_CLASS_OPTIONS: [a4paper,12pt,oneside,openany]
#+latex_header: \usepackage[mark]{gitinfo2}
#+latex_header: \usepackage{mVersion}
#+latex_header: \increaseBuild
#+latex_header: \date{Build - \version}
# #+LaTeX_HEADER: \usepackage[utf8]{inputenc}
# #+LaTeX_HEADER: \usepackage[T1]{fontenc} 
#+LaTeX_HEADER: \usepackage{mathpazo}
#+LaTeX_HEADER: \usepackage{fixltx2e}
#+latex_header: \usepackage[backend=biber,style=philosophy-modern,doi=true,hyperref=true,backref=true,backrefstyle=two,date=year,maxcitenames=3]{biblatex}
#+LATEX_HEADER: \addbibresource{~/research/hair/hair.bib}
#+LATEX_HEADER: \usepackage{makeidx}
#+latex_header: \makeindex
#+latex_header: \usepackage{glossaries}
#+latex_header: \makeglossaries
#+latex_header: \usepackage[unhide]{todo}
#+latex_header: \usepackage{everypage}
#+latex_header: \usepackage{draftwatermark}
#+latex_header: \usepackage{scrextend}
#+latex_header: \usepackage{hyperref}
#+latex_header: \hypersetup{colorlinks,linkcolor={red},citecolor={magenta},urlcolor={blue}}
#+latex_header: \setlength\parindent{0pt} % sets indent to zero
#+latex_header: \usepackage{chngcntr}
#+latex_header: \counterwithout{footnote}{chapter}
#+latex_header: \footnotesep\baselineskip
#+latex_header: \setlength{\parskip}{7pt}
#+OPTIONS: H:3 toc:t \n:nil ::t |:t ^:t f:t tex:t
#+LaTeX: \setcounter{secnumdepth}{0}
#+OPTIONS: toc:2
--8<---------------cut here---------------end--------------->8---

How can I get my org-mode level 4 subheading to appear as subsubsection
when the file is exported please?

Thanks
Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
TGmeds = http://www.tgmeds.org.uk
Debian 8.4, fluxbox 1.3.7, emacs 25.0.92

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[relevance 6%]

* Re: CV, org-mode, and pdf
  @ 2015-09-14 15:46 11% ` Eric S Fraga
  0 siblings, 0 replies; 200+ results
From: Eric S Fraga @ 2015-09-14 15:46 UTC (permalink / raw)
  To: Dan Griswold; +Cc: emacs-orgmode

On Monday, 14 Sep 2015 at 10:31, Dan Griswold wrote:
> Dear org-mode community,
>
> A year ago, there was a thread here, started by Rainer Krug,  on using
> org-mode to produce nice looking CVs.

[...]

> There are two pieces to my solution: first, setting up org-mode with a new
> latex class, "cv"; and then including certain lines at the top of the org
> file that contains the CV.

I do something similar, including your use of top level headings for the
major sections.  However, I use koma-script's article class (scrartcl,
my default latex class) and then have the following in my org file:

#+begin_src org
  ,#+latex_header: \usepackage{fancyhdr}
  ,#+latex_header: \usepackage[includefoot,margin=2cm]{geometry}
  # -------------------- Change the section headings to stand out a little more
  ,#+latex_header: \usepackage{titlesec}
  ,#+latex_header: \titleformat{\section}{\Large\bfseries}{}{0pt}{\color{blue}\centering}[\hrule]
  ,#+latex_header: \titleformat{\subsection}{\large\bfseries}{}{0pt}{\color{blue}}
  # -------------------- remove boxes etc. from links as they look ugly on a printed document
  ,#+latex_header: \hypersetup{colorlinks=true,linkcolor={black},citecolor={black},pagecolor={black}, urlcolor={black}}

  ,#+latex_header: \pagestyle{fancy} \fancyhead{} \renewcommand{\headrulewidth}{0pt} \fancyfoot{} \lfoot{Curriculum Vitae} \cfoot{} \rfoot{Eric S Fraga -- \thepage} \thispagestyle{empty}
  ,#+latex_header: \setlength{\parindent}{0pt}
  ,#+latex_header: \setlength{\parskip}{5pt}
  ,#+latex_header: \sloppy
#+end_src

I could have put all of these in a separate org latex class but since
it's a one-use class, I thought it made more sense to have the
customisations in the org file.  YMMV, of course ;-)

As my cv is rather long, I put a table of contents on the second page
after all of my personal details.

For my list of publications, I use the =etaremune= (enumerate backwards)
environment, as in:

#+begin_src org
  ,#+latex_header: \usepackage{etaremune}

  (much later)
  ,#+attr_latex: :environment etaremune
  1. most recent publication
  2. older one
  3. and so on
#+end_src

HTH (somebody),
eric
-- 
: Eric S Fraga (0xFFFCF67D), Emacs 25.0.50.2, Org release_8.3.1-234-g8c85c9

^ permalink raw reply	[relevance 11%]

* Re: merge trees?
  @ 2015-09-03 19:15  2%     ` Thomas S. Dye
  0 siblings, 0 replies; 200+ results
From: Thomas S. Dye @ 2015-09-03 19:15 UTC (permalink / raw)
  To: Matt Price; +Cc: Org Mode

[-- Attachment #1: Type: text/plain, Size: 937 bytes --]

Aloha Matt,

Matt Price <moptop99@gmail.com> writes:

> sounds interesting, can you send me a copy of the source? I don't usei
> nternal links very much!

Here is a link to the course syllabus and schedule, so you can see the
result:

http://www.tsdye.com/anth_323/anth_323_syllabus.html

My students seem to appreciate the Course Calendar and they definitely
appreciate the ReadTheOrg style.

I've attached the Org mode source, which probably depends on some code
in my library of Babel.  At least you'll be able to see how I structure
the file and use internal links.  I really like using the ID properties
for internal links to headlines, so I'm free to change the headline text
without breaking the link.

Also, there is a bunch of material in the attached file related to
exporting slide-show lectures to pdf, which you can ignore.  I've
stripped out the lecture content because it's not relevant to your
query.

All the best,
Tom


[-- Attachment #2: ANTH 323 syllabus --]
[-- Type: text/x-org, Size: 58311 bytes --]

#+TITLE: Fall 2015 ANTH 323 Pacific Islands Archaeology
#+AUTHOR: Thomas S. Dye
#+LATEX_HEADER: \newcommand{\myuni}{University of Hawai`i at M\={a}noa}

 - Classroom: Saunders Hall 345
 - Meeting Times: MWF 12:30--1:20
 - Instructor: Dr. Thomas S. Dye (tdye@hawaii.edu)
   - Office: Saunders Hall 346B
   - Office Hour: Friday 11:00--12:00, or by appointment

* Syllabus
  :PROPERTIES:
  :EXPORT_FILE_NAME: anth-323-f15-syllabus
  :EXPORT_TITLE: Fall 2015 Syllabus for ANTH 323
  :END:

This course is an introduction to archaeological research in Oceania,
a region including the islands of Polynesia, Melanesia, and
Micronesia. The exploration of this oceanic world, the ability of
Pacific Islanders to colonize remote, environmentally diverse
landforms, and their success developing a range of island societies
represent remarkable achievements in the history of humanity. We will
examine evidence for systematic long-distance voyaging, the human
colonization of previously uninhabited landscapes, and the independent
evolution of cultures descendant from a common ancestral heritage. The
course is open to both undergraduate and graduate students.

The central questions we address are: What is archaeology's place in
the study of Oceania's past alongside oral history, history,
historical linguistics, comparative ethnography, and genetics?  What
have been archaeology's main contributions to the history of Oceania?
What is the future of archaeology in Oceania?

This class is writing intensive. There will be a research paper (10
pages plus bibliography) and other shorter writing assignments. This
course is designed for upper-division undergraduates and graduate
students. We welcome all students with interests in Oceania. A
background in archaeology is helpful but not a prerequisite.

** Textbook

The required textbook for this semester is Patrick Kirch's /On the
Road of the Winds:/ /An Archaeological History of the Pacific Islands
before European Contact/.

Kirch is an emeritus professor at the University of California
Berkeley.  He grew up in M\amacron{}noa, attended Punahou School, earned a
Bachelor's degree at the University of Pennsylvania, and went on to
earn a PhD in Anthropology at Yale University. He has an unparalleled
range of archaeological experience throughout the Pacific starting
when he was a teenager in Hawai`i and continuing today.  He is:
  - an avid reader about all things Pacific who has made contributions
    to the fields of linguistics and anthropology, in addition to archaeology;
  - a strong proponent of a multi-disciplinary approach that
    integrates archaeology with various natural sciences, linguistics,
    and ethnography;
  - a prolific author with a fluid writing style.

We will read and discuss the book critically, focusing primarily on
the archaeological materials and secondarily on the relationship of
archaeological evidence to other kinds of evidence.  In addition, in
class discussions and through students' term paper research, we will
discuss findings made since the textbook was published more than a
decade ago.

** Class Meetings

The class meets Monday, Wednesday, and Friday from 12:30 to 1:20 in
Saunders Hall 345.  The class is organized as a seminar, so please sit
at the table.

The course is structured to maximize discussion time during class
meetings.  The successful student will come to class well-prepared and
eager to engage in discussion.  In particular, please prepare for
class by completing the reading and pondering the discussion questions.

All inquiry begins with doubt.  Please come to class with questions of
your own!

Tip: Discuss your term paper research in class, as appropriate.  The
responses you get from your instructor and fellow students might help
you understand your term paper topic in a new or interesting way.

** Grading

Your grade will be based on the total number of points you earn in the
mid-term examination, research paper, discussion papers, annotated
maps, and class participation.  Note that you must complete the final
term paper and turn it in on time to pass the course.

*** Distribution of Points

There are 127 possible points. Their distribution is as follows:


 | Assignment                                    |                Points |
 |-----------------------------------------------+-----------------------|
 | [[id:6AB45747-EFFB-46C3-B93F-C91C49CB0E8B][A mid-term examination]]                        |                    15 |
 |                                               |                       |
 | [[id:FE11B1CA-0F84-4322-8FD1-C8F8D24DB543][A term paper]]                                  |              64 total |
 | Step 1. Topic                                 |                     2 |
 | Step 2. Report on research to form questions  |                     2 |
 | Step 3. Refined proposal (1 page)             |                     2 |
 | Step 4. Research pitch session                |                     2 |
 | Step 5. Abstract and bibliography (2 pages)   |                     4 |
 | Step 6. Introduction and outline (2 pages)    |                     4 |
 | Step 7. Two body paragraphs (2 pages)         |                     4 |
 | Step 8. First draft (10 pages + bibliography) |                    20 |
 | Step 9. Final draft (10 pages + bibliography) |                    20 |
 | Step 10. Class presentation                   |                     4 |
 |                                               |                       |
 | [[id:35E7B1F0-9AF3-4F12-B792-71ED9C2BE5E6][Six discussion papers]] (1--2 pages each)       |      3 each, 18 total |
 | [[id:8FC1339A-03C8-4F1C-9B29-D7D752174B3B][Seven annotated maps]]                          |      2 each, 14 total |
 | [[id:CB24D8B4-60E8-41EA-AE33-9B9A9761B58E][Sixteen weeks of class participation]]          | 1 each week, 16 total |
 | TOTAL                                         |                   127 |

*** Grading Scale
Students who complete the term paper and turn it in on time will be
graded on the following point scale.

| Grade |   Points |
|-------+----------|
| A+    | 101--127 |
| A     |  94--100 |
| A-    |   90--93 |
| B+    |   87--89 |
| B     |   84--86 |
| B-    |   80--83 |
| C+    |   77--79 |
| C     |   74--76 |
| C-    |   70--73 |
| D+    |   67--69 |
| D     |   64--66 |
| D-    |   60--63 |
| F     |    0--59 |

** Term Paper Schedule

| Date      | Assignment                                         |
|-----------+----------------------------------------------------|
| 9/4 (F)   | [[id:B0AC070B-B855-4C7E-86CE-3A61CFCDFC7B][Step 1. Choose topic]]                               |
| 9/11 (F)  | [[id:2FCB770C-8B4D-4C5F-8A99-0A6135F00272][Step 2. Form questions (1 page)]]                    |
| 9/18 (F)  | [[id:D8A45370-E7AD-4353-9B9D-D129218DC5FF][Step 3. Refine proposal (1 page)]]                   |
| 9/23 (W)  | [[id:138B03A7-9B87-4098-BD44-FC91FDD80019][Step 4. Pitch research]]                             |
| 10/2 (F)  | [[id:572B02A2-3033-49B9-B116-3572FC837760][Step 5. Abstract and bibliography (2 pages)]]        |
| 10/9 (F)  | [[id:221B8BD9-1A77-4D87-8632-B5E64254A1D7][Step 6. Introduction and outline (2 pages)]]         |
| 10/16 (F) | [[id:1B3777A1-553F-4E48-B10A-C2197AE4E635][Step 7. Two body paragraphs (2 pages)]]              |
| 10/30 (F) | [[id:E731767D-7E28-4114-81C5-0D2737E71DB7][Step 8. First draft (10 pages + bibliography)]]      |
| 12/4 (F)  | [[id:5E480E65-3DA3-4FB5-B371-43286244854F][Step 9. Final term paper (10 pages + bibliography)]] |
| 12/4 (F)  | [[id:C5E8760C-8F92-4A8D-BD7C-9FDF5A3759E2][Step 10. Class presentation]]                        |
| 12/7 (M)  | [[id:C5E8760C-8F92-4A8D-BD7C-9FDF5A3759E2][Step 10. Class presentation]]                        |
| 12/9 (W)  | [[id:C5E8760C-8F92-4A8D-BD7C-9FDF5A3759E2][Step 10. Class presentation]]                        |

** Stipulations

 - Writing assignments must be submitted as Portable Document Format
   (pdf) files via Laulima
 - Maps can be submitted as graphic files via Laulima, or as marked up
   hard copy submitted at the start of class on the due date
 - No credit for late assignments without a written medical excuse
 - Steps 1--10 of the Research Paper are /required/, whether or not you
   choose to submit Steps 1--3 and 5--8 for points on or before the
   due date
   - You /must/ attend class on 9/23 (W) to complete Step 4
   - You /must/ attend class on 12/4 (F), 12/7 (M), and/or 12/9 (W) to
     complete Step 10
   - Final term papers /will not be accepted/ after the due date and time
   - Failure to submit a final term paper on time results in a failing
     grade for the course

** The Writing Center

Many students lack confidence in their writing ability.  Fortunately,
good writing is a skill that can be acquired with study and practice.
If you want to improve your writing skills, please explore the
services offered on campus by the [[https://sites.google.com/a/hawaii.edu/writingcenter/appointments][Writing Center]] in the English
Department.

** Reasonable Accommodations
If you feel that you need reasonable accommodations because of
the impact of a disability:
 - contact the [[http://www.hawaii.edu/kokua/][KOKUA Program]] at 956--7511 or 956--7612 in room 013 of the QLCSS
 - speak with me privately to discuss your specific needs
I will be happy to work with you and the [[http://www.hawaii.edu/kokua/][KOKUA Program]] to meet your
access needs related to a documented disability.

* Course Calendar
  :PROPERTIES:
  :ID:       B76B9F9E-9E38-41EE-B83A-8ED1AF3BE974
  :END:
| Day       | Topic                                  | Preparation                                                      | Assignment due                                                             |
|-----------+----------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------|
| 8/24 (M)  | Introduction to ANTH 323               |                                                                  |                                                                            |
| 8/26 (W)  | What is Pacific Islands archaeology?   | [[file:anth-323-archaeology.pdf][Lecture: What is Archaeology?]]  [[*Lecture 1, What is Archaeology?][Discussion questions]]              | [[id:C1FF83F1-E5D3-4F4A-B1E6-44BEF4EA13EA][Annotated map 1]]                                                            |
| 8/28 (F)  |                                        | Textbook: Introduction [[id:176B8682-109F-463A-A07A-CFA9BA3E3C56][Discussion questions]]                      | [[id:5866BEA8-07D2-45E1-BF83-584412A58AB9][Annotated map 2]]                                                            |
| 8/31 (M)  | History of archaeological research     | Textbook: Chapter 1 [[id:AC360A4E-372C-41A7-9536-D7E41BE580FA][Discussion questions]]                         | [[id:5DF8980B-9639-4B37-92B1-85BE50825D37][Annotated map 3]]                                                            |
| 9/2 (W)   |                                        |                                                                  |                                                                            |
| 9/4 (F)   | Topics in Pacific Islands archaeology  |                                                                  | [[id:B0AC070B-B855-4C7E-86CE-3A61CFCDFC7B][Step 1: Choose topic]]                                                       |
| 9/7 (M)   | Holiday                                | No class                                                         |                                                                            |
| 9/9 (W)   | Environmental setting                  | Textbook: Chapter 2 [[id:61D64EB7-E558-42F6-B136-5182C15F3379][Discussion questions]]                         | [[id:4AF61A5B-F0D2-4833-8BB8-0626EA29D244][Discussion paper 1 (1-2 pages)]], [[id:F4F10555-5978-49B4-A14A-1FDE6E8B758E][Annotated map 4]]                            |
| 9/11 (F)  | Where do I start?                      |                                                                  | [[id:2FCB770C-8B4D-4C5F-8A99-0A6135F00272][Step 2: Form questions (1 page)]]                                            |
| 9/14 (M)  | Faint traces from the Pleistocene      | Textbook: Chapter 3 [[id:9BF242C1-5BD3-4344-85C4-DECAD387FA56][Discussion questions]]                         | [[id:009BA056-1921-4F84-8389-CDBD8B54CD45][Discussion paper 2 (1-2 pages)]]                                             |
| 9/16 (W)  |                                        |                                                                  |                                                                            |
| 9/18 (F)  | Developing a research focus            |                                                                  | [[id:D8A45370-E7AD-4353-9B9D-D129218DC5FF][Step 3: Refine proposal (1 page)]]                                           |
| 9/21 (M)  | The Lapita horizon                     | Textbook: Chapter 4 [[id:5A38DE98-633B-4993-9CB5-881E50ABE258][Discussion questions]]                         | [[id:3C9B7DC2-D124-433A-92C7-A6DB8E7B4186][Annotated map 5]]                                                            |
| 9/23 (W)  | Class presentations                    |                                                                  | [[id:138B03A7-9B87-4098-BD44-FC91FDD80019][Step 4: Pitch research]]                                                     |
| 9/25 (F)  |                                        |                                                                  |                                                                            |
| 9/28 (M)  |                                        | [[https://www.youtube.com/watch?v=DWp5MiiVR1k][Movie: The Wayfinders]] [[id:C2266D7F-EDE0-400A-A771-08D79DB69309][Discussion questions]]                       |                                                                            |
| 9/30 (W)  |                                        |                                                                  |                                                                            |
| 10/2 (F)  | Scholarly citations                    |                                                                  | [[id:572B02A2-3033-49B9-B116-3572FC837760][Step 5: Abstract and bibliography (2 pages)]]                                |
| 10/5 (M)  | [[id:6AB45747-EFFB-46C3-B93F-C91C49CB0E8B][Mid-term examination]]                   |                                                                  |                                                                            |
| 10/7 (W)  | Post-Lapita developments in the west   | Textbook: Chapter 5 [[id:BBAC7E77-31C5-4317-A208-94C6859A4513][Discussion questions]]                         | [[id:80BADA59-E24D-490A-AD5F-7BCBCC944298][Discussion paper 3 (1-2 pages)]], [[id:96EBDB24-E208-4151-87FB-1D41C2282A8F][Annotated map 6]]                            |
| 10/9 (F)  | Outlining your term paper              |                                                                  | [[id:221B8BD9-1A77-4D87-8632-B5E64254A1D7][Step 6: Introduction and outline (2 pages)]]                                 |
| 10/12 (M) |                                        |                                                                  |                                                                            |
| 10/14 (W) |                                        |                                                                  |                                                                            |
| 10/16 (F) | Writing your term paper                |                                                                  | [[id:1B3777A1-553F-4E48-B10A-C2197AE4E635][Step 7: Two body paragraphs (2 pages)]]                                      |
| 10/19 (M) | Northwestern Remote Oceania            | Textbook: Chapter 6 [[id:10862712-70F7-4650-9DCD-39AF74E6FC2F][Discussion questions]]                         | [[id:5AD19156-D305-4102-ACA5-D362335CAEB6][Discussion paper 4 (1-2 pages)]]                                             |
| 10/21 (W) |                                        |                                                                  |                                                                            |
| 10/23 (F) |                                        |                                                                  |                                                                            |
| 10/26 (M) | Getting it all together (sort of)      |                                                                  | [[id:CCB59B44-AB9F-4609-811E-1046C2ECFD98][Annotated map 7]]                                                            |
| 10/28 (W) |                                        |                                                                  |                                                                            |
| 10/30 (F) |                                        |                                                                  | [[id:E731767D-7E28-4114-81C5-0D2737E71DB7][Step 8: First draft (10 pages + bibliography)]]                              |
| 11/2 (M)  | The final phase of human dispersal     | Textbook: Chapter 7 [[id:68FBA2A7-FF17-44B7-90E7-A7DE1AFB8638][Discussion questions]]                         |                                                                            |
| 11/4 (W)  |                                        |                                                                  |                                                                            |
| 11/6 (F)  |                                        | Lecture: The Radiocarbon Revolution, [[*Lecture 2, The Radiocarbon Revolution][Discussion questions]]        |                                                                            |
| 11/9 (M)  |                                        |                                                                  |                                                                            |
| 11/11 (W) | Holiday                                | No class                                                         |                                                                            |
| 11/13 (F) |                                        |                                                                  |                                                                            |
| 11/16 (M) | Developments in Eastern Remote Oceania | Textbook: Chapter 8 [[id:E110D6D8-4F1E-476A-8FD5-5F551968DDEA][Discussion questions]]                         |                                                                            |
| 11/18 (W) |                                        | Lecture: The Kingdoms of Tonga and Hawai`i, [[*Lecture 3, The Kingdoms of Tonga and Hawai`i][Discussion questions]] |                                                                            |
| 11/20 (F) |                                        |                                                                  |                                                                            |
| 11/23 (M) |                                        |                                                                  |                                                                            |
| 11/25 (W) |                                        |                                                                  | [[id:246C4EB5-7FC1-4CB9-9330-AA9D621B0DD8][Discussion paper 5 (1-2 pages)]]                                             |
| 11/27 (F) | Holiday                                | No class                                                         |                                                                            |
| 11/30 (M) | Archaeology's role in Pacific history  | Textbook: Chapter 9 [[id:4CE3AC6E-BABB-4C01-9457-3EB80C575498][Discussion questions]]                         |                                                                            |
| 12/2 (W)  |                                        |                                                                  |                                                                            |
| 12/4 (F)  | Class Presentations                    |                                                                  | [[id:5E480E65-3DA3-4FB5-B371-43286244854F][Step 9: Final term paper (10 pages + bibliography)]], [[id:C5E8760C-8F92-4A8D-BD7C-9FDF5A3759E2][Step 10: Presentations]] |
| 12/7 (M)  | Class Presentations                    |                                                                  | [[id:C5E8760C-8F92-4A8D-BD7C-9FDF5A3759E2][Step 10: Presentations]]                                                     |
| 12/9 (W)  | Class Presentations                    |                                                                  | [[id:B76B9F9E-9E38-41EE-B83A-8ED1AF3BE974][Step 10: Presentations]]                                                     |

* Term Paper
  :PROPERTIES:
  :EXPORT_FILE_NAME: anth-323-f15-term-paper
  :EXPORT_TITLE: ANTH 323 Term Paper Schedule
  :ID:       FE11B1CA-0F84-4322-8FD1-C8F8D24DB543
  :END:

In this course you will undertake a term-long writing project on the
general topic of Pacific Islands archaeology.  Please write about a
specific topic that particularly interests you.  Your topic might
concern:
 - some facet of archaeological practice in the Pacific
 - the history of archaeological research in an island, island group, or region
 - Pacific Islands archaeology in its disciplinary nexus, such as its
   relationship to the physical and life sciences or to written and
   oral history
 - an archaeological assemblage from a particular island, island group, or region
 - an archaeological sequence from an island, island group, or region
 - a cha\icirc{}ne op\eacute{}ratoire for a particular artifact
 - archaeological evidence for a cultural process of some kind
 - archaeological evidence for or against a particular theory of
   change or development

** Choose topic (Friday 9/4)
   :PROPERTIES:
   :ID:       B0AC070B-B855-4C7E-86CE-3A61CFCDFC7B
   :END:

Your first task is to focus the topic more sharply. Remember:
"topics" are broad. Your initial proposal will state your
topic and list some preliminary questions that you hope to
investigate.

** Form questions (Friday 9/11)
   :PROPERTIES:
   :ID:       2FCB770C-8B4D-4C5F-8A99-0A6135F00272
   :END:

Different topics suggest different strategies, including consulting
special subject encyclopedias, referring to peer-reviewed journals,
and even using Google. As we talk about how to use sources to refine
your thinking, you will also learn how to find the information that
you need. We will also talk about what to do when, for instance, you
find material that undermines your initial premise, or sources that
are at odds with each other. We will discuss how to use sources
responsibly.

** Refine proposal (Friday 9/18)
   :PROPERTIES:
   :ID:       D8A45370-E7AD-4353-9B9D-D129218DC5FF
   :END:

Research requires the continual refinement of a topic and a set of
research questions. Accordingly, you are likely to challenge your
initial premises and arrive at various conclusions as you work. For
this assignment, you should present a refined proposal and a set of
focused questions that reflect your current thinking about your
research.

** Pitch research (Wednesday 9/23)
   :PROPERTIES:
   :ID:       138B03A7-9B87-4098-BD44-FC91FDD80019
   :END:

Here you will pitch your research plan in class. Your “pitch session”
should include a succinct statement of your proposed argument, the
questions you intend to address, and some plan for
addressing/researching these questions. Your classmates' and
instructor's responses will help you to see the strengths and
weaknesses of your research plan.

** Abstract and bibliography (Friday 10/2)
   :PROPERTIES:
   :ID:       572B02A2-3033-49B9-B116-3572FC837760
   :END:

Write a 75 word abstract summarizing the paper you think you're going
to write. Attach a draft of your bibliography. This bibliography
should identify a list of five or more sources that include books,
journals, and on-line resources.  You can use Google and Wikipedia as
much or little as you like, but your bibliography /must/ include
some books and journal articles.

** Introduction and outline (Friday 10/9)
   :PROPERTIES:
   :ID:       221B8BD9-1A77-4D87-8632-B5E64254A1D7
   :END:

By this step, you should have a working thesis and introduction for
your term paper. Your introduction should contextualize your thesis
and engage your reader. It should also offer the reader a suggestion
of your paper's structure.

** Two body paragraphs (Friday 10/16)
   :PROPERTIES:
   :ID:       1B3777A1-553F-4E48-B10A-C2197AE4E635
   :END:

You will write, and your classmates and instructor will review, a
couple of body paragraphs in class to determine how well you've set
up, employed, analyzed, and cited your sources. A discussion of
plagiarism is included here.

** First draft (Friday 10/30)
   :PROPERTIES:
   :ID:       E731767D-7E28-4114-81C5-0D2737E71DB7
   :END:

Here your goal is to produce a coherent whole.  The draft can be rough
but it should have an introduction, a body, and a conclusion.  It also
needs in-text citations and a bibliography of references cited! You
will receive feedback on your draft.

"Write your first draft with your heart. Re-write with your head."
~ from the movie /Finding Forrester/

** Final term paper (Friday 12/4)
   :PROPERTIES:
   :ID:       5E480E65-3DA3-4FB5-B371-43286244854F
   :END:

"I'm not a very good writer, but I'm an excellent rewriter." ~ James Michener

** Class presentation (Friday 12/4 through Wednesday 12/9)
   :PROPERTIES:
   :ID:       C5E8760C-8F92-4A8D-BD7C-9FDF5A3759E2
   :END:

Your research presentation should /not/ be a simple "replay" of your
topic but should be re-designed so that you
 - spend some time talking spontaneously
 - employ more than one medium 
 - engage your classmates in discussion 

A successful presentation will focus on one part of the research,
without trying to cover all of the research in your paper. You will
have twenty minutes to make your presentation; this will include time
devoted to questions and answers.

Your presentation will be graded separately from your paper.

* Mid-term Examination
  :PROPERTIES:
  :ID:       6AB45747-EFFB-46C3-B93F-C91C49CB0E8B
  :END:
The mid-term examination consists of three questions chosen from the
Discussion Questions from [[*Lecture 1, What is Archaeology?][Lecture 1]], [[id:AC360A4E-372C-41A7-9536-D7E41BE580FA][Chapter 1]], [[id:61D64EB7-E558-42F6-B136-5182C15F3379][Chapter 2]],
[[id:9BF242C1-5BD3-4344-85C4-DECAD387FA56][Chapter 3]], and [[id:5A38DE98-633B-4993-9CB5-881E50ABE258][Chapter 4]].  Each answer is worth a maximum of five
points, for a total of 15 points.
 
* Discussion Papers
  :PROPERTIES:
  :ID:       35E7B1F0-9AF3-4F12-B792-71ED9C2BE5E6
  :END:

You can complete up to six discussion papers, each of which is 1--2
pages long, optionally including a bibliography, and worth a maximum
of 3 points.  Choose a discussion question from the appropriate list
and write a well-structured, short essay that attempts to answer it.
Each discussion paper should have an introductory paragraph, one or
more body paragraphs, and a conclusion paragraph.

<<logic>>
Where appropriate, please consider the three step logic of
archaeological inquiry as it relates to your discussion question:
 - acquisition: prepare an artifact assemblage for study
 - construction: abstract a quality used to classify and/or
     measure the artifact assemblage in order to find patterns in
     content, space, and/or time
 - reconstitution: elaborate a reason for the structure found in the
      artifact assemblage, either a
  - social scientific law: universal quality of human behavior,
       irrespective of time and place, or a
  - historical process: change in human behavior in the context of
       a particular time and place

** Discussion Paper 1
   :PROPERTIES:
   :ID:       4AF61A5B-F0D2-4833-8BB8-0626EA29D244
   :END:
Please select an appropriate question from either [[id:176B8682-109F-463A-A07A-CFA9BA3E3C56][Introduction]],
[[id:AC360A4E-372C-41A7-9536-D7E41BE580FA][Chapter 1, Discovering the Oceanic Past]], or [[id:61D64EB7-E558-42F6-B136-5182C15F3379][Chapter 2, The Pacific
Islands as a Human Environment]] for this discussion paper.

** Discussion Paper 2
   :PROPERTIES:
   :ID:       009BA056-1921-4F84-8389-CDBD8B54CD45
   :END:
Please select an appropriate question from [[id:9BF242C1-5BD3-4344-85C4-DECAD387FA56][Chapter 3, Sahul]] for this
discussion paper.

** Discussion Paper 3
   :PROPERTIES:
   :ID:       80BADA59-E24D-490A-AD5F-7BCBCC944298
   :END:

Please select an appropriate question from either [[id:5A38DE98-633B-4993-9CB5-881E50ABE258][Chapter 4, Lapita
Expansion]] or [[id:BBAC7E77-31C5-4317-A208-94C6859A4513][Chapter 5, Post-Lapita Melanesia]] for this discussion paper.

** Discussion Paper 4
   :PROPERTIES:
   :ID:       5AD19156-D305-4102-ACA5-D362335CAEB6
   :END:
Please select an appropriate question from [[id:10862712-70F7-4650-9DCD-39AF74E6FC2F][Chapter 6, Micronesia]] for
this discussion paper.

** Discussion Paper 5
   :PROPERTIES:
   :ID:       246C4EB5-7FC1-4CB9-9330-AA9D621B0DD8
   :END:
Please select an appropriate question from either [[id:68FBA2A7-FF17-44B7-90E7-A7DE1AFB8638][Chapter 7,
Polynesian Dispersal]] or [[id:E110D6D8-4F1E-476A-8FD5-5F551968DDEA][Chapter 8, Polynesian Developments]] for this
discussion paper.

** Discussion Paper 6
Please pick an appropriate question from [[id:4CE3AC6E-BABB-4C01-9457-3EB80C575498][Chapter 9, Reconstitution]] for
this discussion paper.

* Discussion Questions
Questions from the following lists will likely be discussed in class
(depending on where the conversation leads us).  You should come to
class prepared to talk about them.  You will choose your [[id:35E7B1F0-9AF3-4F12-B792-71ED9C2BE5E6][Discussion
Paper]] topics from them. Also, the questions on the [[*Mid-term Examination][mid-term
examination]] will be selected from these lists.

The lists are ordered in the order we're likely to discuss them in class
(depending on where the conversation leads us).  Please refer to the [[*Course
 Calendar][Course Calendar]] for more detailed information on scheduling.

** Lecture 1, What is Archaeology?
- How is archaeology different from history?
- How is historicism different from social science?
- Why study archaeology?
- Is the temple on L\amacron{}na`i Island a site?  Why, or why not?
- What is the necessary condition of inquiry?  Is scientific inquiry
  fundamentally different from other forms of inquiry?  Why or why
  not?
- List the three logical steps of [[logic][archaeological inquiry]] and describe
  them in your own terms.



** Introduction
   :PROPERTIES:
   :ID:       176B8682-109F-463A-A07A-CFA9BA3E3C56
   :END:
- How can one study change with /synchronic/ data?  How with
  /diachronic/ data?  Do the study processes differ?
** Chapter 1, Discovering the Oceanic Past
   :PROPERTIES:
   :EXPORT_FILE_NAME: anth-323-f15-discovering
   :ID:       AC360A4E-372C-41A7-9536-D7E41BE580FA
   :END:

 - Who were Peter Buck and Te Rangi Hiroa?  List some of
   their most influential publications and discuss how their careers
   intersected with Pacific Islands archaeology.
 - What is time depth?  How have scholarly views on the time depth of
   Oceanic history changed since the nineteenth century?
 - Does the caption to Figure 1.16 use the terms "site" and "artifact"
   as they were defined in Lecture: What is Archaeology?  If not, how
   might the caption be re-written to accommodate those definitions?
 - Who was Roger Green and what were some of his accomplishments?
 - Which universities have played major roles in Oceanic
   archaeological research?
 - How has racism affected the study of Oceanic history?  At which
   stage of archaeological inquiry is racism most likely to appear?

** Chapter 2, The Pacific Islands as a Human Environment
   :PROPERTIES:
   :EXPORT_FILE_NAME: anth-323-f15-environment
   :ID:       61D64EB7-E558-42F6-B136-5182C15F3379
   :END:

 - Describe Near Oceania, Remote Oceania, Melanesia, Polynesia, and
   Micronesia in terms of their relationship to tectonic plates. How
   is tectonic plate movement related to the geographic distribution
   of islands in an island group, such as Hawai`i and the Marquesas?
 - What processes are responsible for each of the four main types of
   island in Oceania: Island-arc, High, Atoll, and Makatea?  What
   type of island is O`ahu?
 - What is an ENSO?  How might ENSO have affected the dispersal of
   humans through the Pacific?
 - Describe the general pattern of plant and animal diversity in
   Oceania.  Is there a relationship between diversity and biomass?
   What is the pattern of marine life biomass as one moves away from
   the shoreline of an Oceanic island?
 - What are the two fundamental features of island ecosystems?
   Describe the regional variation of these fundamental features
   across Oceania.  How might these features have affected the
   dispersal of humans through the Pacific?
 - Describe how one might determine whether or not Oceanic peoples
   practiced a "conservation ethic."  Is this a useful exercise?
   Why, or why not?


** Chapter 3, Sahul
   :PROPERTIES:
   :EXPORT_FILE_NAME: anth-323-f15-sahul
   :ID:       9BF242C1-5BD3-4344-85C4-DECAD387FA56
   :END:

 - What is Sahul?  How is it related to the islands of Near Oceania?
 - What kinds of artifact characterize Pleistocene sites in Near
   Oceania?  How old are they?
 - What is the evidence for agriculture at Kuk Swamp in Highland New
   Guinea?  How old is it?
 - What is arboriculture and when does archaeological evidence suggest
   it was developed in Near Oceania?
 - What is the geographic distribution of malaria in Oceania today?
   What influence might the disease have had on Oceanic history?

** Chapter 4, Lapita Expansion
   :PROPERTIES:
   :ID:       5A38DE98-633B-4993-9CB5-881E50ABE258
   :END:
- Compare and contrast these two interpretations of the appearance of
  the Lapita cultural complex in Near Oceania
  - an indigenous, in situ development from previously established
    cultural traditions
  - entirely new, intrusive cultural complex that replaced previously
    established cultural traditions
- What routes did the Lapita pottery making explorers follow in their
  dispersal into Remote Oceania?  Is the dispersal process reflected
  in the radiocarbon dating evidence shown in Figure 4.5?  Why, or
  why not?
- What are the various "push" and "pull" factors that scholars have
  advanced to explain the Lapita "engine of exploration and
  colonization"?  Can these be distinguished with archaeological
  materials?  Why, or why not?
- What plants did the Lapita pottery making people grow for food?
  Where did these plants originate?  Where were they domesticated?
- What is the archaeological evidence for the "inter-group
  competition" (p. 115) ascribed to the Lapita pottery making
  peoples?  

** The Wayfinders
   :PROPERTIES:
   :ID:       C2266D7F-EDE0-400A-A771-08D79DB69309
   :END:
 - Mau Piailug died on his home island of Satawal in 2010.  If the
   Polynesian Voyaging Society had started building the voyaging
   canoe H\omacron{}k\umacron{}le`a in 2011, would she have made a non-instrumental
   voyage to Tahiti?  Why or why not?
 - What obstacles did Nainoa Thompson overcome to sail H\omacron{}k\umacron{}le`a to
   Tahiti in 1976?  Which of these do you think were most difficult
   to overcome?  Why?
 - What role did archaeology play in the voyages of H\omacron{}k\umacron{}le`a?

** Chapter 5, Post-Lapita Melanesia
   :PROPERTIES:
   :ID:       BBAC7E77-31C5-4317-A208-94C6859A4513
   :END:

- This chapter reviews post-Lapita history in the islands of
  Melanesia and sets aside the post-Lapita history of Tonga and Samoa
  for a later chapter.  Discuss the decision to structure the
  narrative this way in the light of the discussion in the section
  entitled /Defining Oceania/ on pages 4--6.
- The section entitled /Change in Ceramic Sequences/ (p. 161--162)
  presents two models to explain post-Lapita pottery sequences in
  Melanesia.  Compare and contrast the two models.  Are they similar
  to, or different from, the model used to explain the distribution
  of Lapita pottery?
- Contemplate the model of changing exchange network configurations
  in Figure 5.27.  How many dimensions does the model have?  How
  might an archaeologist measure each of the dimensions?  Are there
  other archaeologically measurable dimensions of exchange networks
  not included in the model?

** Chapter 6, Micronesia
   :PROPERTIES:
   :ID:       10862712-70F7-4650-9DCD-39AF74E6FC2F
   :END:
- Describe the discrepancy between initial settlement date estimates in
  Western Micronesia based on paleoenvironmental coring and on
  archaeological data.  What do you think is the most likely
  explanation of the discrepancy?  Why?
- When did atoll islets in Eastern Micronesia form?  How did this
  timing affect settlement and subsequent history?
- Describe the changing configuration of Lelu between initial
  settlement of Kosrae and AD 1800. How did the pace of change vary?

** Chapter 7, Polynesian Dispersal
   :PROPERTIES:
   :ID:       68FBA2A7-FF17-44B7-90E7-A7DE1AFB8638
   :END:

- The characterization of Ancestral Polynesian society using the
  triangulation method shows "the limitations of any archaeological
  sample" (p. 218).  What are these limitations?  Does the
  triangulation method leverage archaeology's strengths?
- The "long pause" in Western Polynesia and a short chronology for
  Eastern Polynesia are now generally accepted.  The arguments in the
  textbook for no pause in dispersal and for a long Eastern
  Polynesian chronology are disproved.  Apply the [[logic][logic of
  archaeological inquiry]] to these arguments.  At which
  step---acquisition, construction, or reconstitution---do they run
  off the rails?
- What is the distribution of Archaic Phase artifact assemblages in
  Eastern Polynesia?  How old are they?
- Apply the [[logic][logic of archaeological inquiry]] to /A Possible Model of
  Eastern Polynesian Dispersals/ on p. 244--245.  What evidence is
  acquired and how is it structured and reconstituted?  Is the
  acquired evidence synchronic, diachronic, or both?

** Lecture 2, The Radiocarbon Revolution
- What distinguishes Bayesian calibration of radiocarbon dates from
  ad-hoc approaches?  What are the pros and cons of Bayesian
  calibration? 
- Compare and contrast the histories of settlement date estimates in
  Hawai`i and New Zealand.  Which steps in the [[logic][logic of
  archaeological inquiry]] account for the similarities and
  differences?
- Is the settlement date an important datum for the [[logic][reconstitution
  step]]?  Why or why not?


** Chapter 8, Polynesian Developments
   :PROPERTIES:
   :ID:       E110D6D8-4F1E-476A-8FD5-5F551968DDEA
   :END:
- Based on its organization and the material it chooses to present,
  does this chapter take a historical approach to Polynesia's past or
  a social scientific one?  Cite examples to support your position.
- Describe Irving Goldman's three-part classification of contact-era
  Polynesian societies that is used to organize the presentation of
  archaeological materials.  What kinds of society are discussed in
  this chapter?  Why?
- Read carefully the full paragraph in the left-hand column on page
  265 that compares the archaeological records of Mangaia and the
  Marquesas.  What processes and events explain the similarities and
  differences in their archaeological records?
- Compare and contrast the cultural periods for the Stratified
  society of Hawai`i in Figure 8.28, with the periods in the cultural
  sequence of the Open society of the Marquesas in Figure 8.6.
- Figure 8.28 constructs a cultural sequence for Hawai`i nei using
  six categories of evidence.  Based on the text pages 291--300 and
  the footnotes, identify the evidence cited in support of each
  category of cultural change.  For each category, how much of the
  evidence comes from archaeology?  (Note: you don't need to read the
  sources cited in the text and footnotes.)
- Figures 8.31 and 8.32 present five graphs that are said to measure
  population growth.  Ignoring the differences in presentation,
  describe the population history illustrated by each graph.  Are
  they the same, or different?  Do they support the population growth
  scenario outlined for the cultural sequence?  Why?
** Lecture 3, The Kingdoms of Tonga and Hawai`i
- What effect might geography have had on the different developmental
  trajectories evidenced by Tonga and Hawai`i?
- What effect might time have had on the different developmental
  trajectories evidenced by Tonga and Hawai`i?

** Chapter 9, Reconstitution
   :PROPERTIES:
   :ID:       4CE3AC6E-BABB-4C01-9457-3EB80C575498
   :END:
- What are surplus production and autoconsumption?  What was the role
  of surplus in Pacific Islands history?
- What is meant by "the political economy of dynamic landscapes"
  (pages 313--317)?
- What is the role of comparison in Pacific Islands archaeology?
  What archaeological materials are best for comparison?  What are
  some of the factors in the Pacific that make comparisons fruitful?
* Map Annotations
  :PROPERTIES:
  :ID:       8FC1339A-03C8-4F1C-9B29-D7D752174B3B
  :END:
You can complete up to seven map annotations, each of which is worth a
maximum of two points.
** Main island groups
   :PROPERTIES:
   :ID:       C1FF83F1-E5D3-4F4A-B1E6-44BEF4EA13EA
   :END:

Identify the main island groups of the Pacific.  

You can choose to:
 - print this [[file:maps/Oceania-blank.pdf][pdf version of the map]], mark it up with a pencil, and
   turn in the paper map at class time, or
 - edit this [[file:maps/Oceania-blank.svg][vector graphics version of the map]] with appropriate
   software and turn in the map graphic on Laulima.

** Regions of Oceania
   :PROPERTIES:
   :ID:       5866BEA8-07D2-45E1-BF83-584412A58AB9
   :END:

Identify the regions of Near Oceania, Remote Oceania, Melanesia,
Micronesia, and Polynesia.

You can choose to:
 - print this [[file:maps/Oceania-blank.pdf][pdf version of the map]], mark it up with a pencil, and
   turn in the paper map at class time, or
 - edit this [[file:maps/Oceania-blank.svg][vector graphics version of the map]] with appropriate
   software and turn in the map graphic on Laulima.

** Locations of Early Archaeological Research
   :PROPERTIES:
   :ID:       5DF8980B-9639-4B37-92B1-85BE50825D37
   :END:

Identify the locations of the earliest archaeological research in the
Pacific.  

You can choose to:
 - print this [[file:maps/Oceania-blank.pdf][pdf version of the map]], mark it up with a pencil, and
   turn in the paper map at class time, or
 - edit this [[file:maps/Oceania-blank.svg][vector graphics version of the map]] with appropriate
   software and turn in the map graphic on Laulima.

** Pleistocene Site Locations
   :PROPERTIES:
   :ID:       F4F10555-5978-49B4-A14A-1FDE6E8B758E
   :END:

Identify the island groups with known Pleistocene sites.  

You can choose to:
 - print this [[file:maps/Oceania-blank.pdf][pdf version of the map]], mark it up with a pencil, and
   turn in the paper map at class time, or
 - edit this [[file:maps/Oceania-blank.svg][vector graphics version of the map]] with appropriate
   software and turn in the map graphic on Laulima.

** Distribution of Sites with Lapita Pottery
   :PROPERTIES:
   :ID:       3C9B7DC2-D124-433A-92C7-A6DB8E7B4186
   :END:

Identify the geographic limits of sites with Lapita pottery and draw
arrows to show the routes of dispersal into Remote Oceania.

You can choose to:
 - print this [[file:maps/Oceania-blank.pdf][pdf version of the map]], mark it up with a pencil, and
   turn in the paper map at class time, or
 - edit this [[file:maps/Oceania-blank.svg][vector graphics version of the map]] with appropriate
   software and turn in the map graphic on Laulima.

** Distribution of Post-Lapita Incised Pottery Traditions
   :PROPERTIES:
   :ID:       96EBDB24-E208-4151-87FB-1D41C2282A8F
   :END:

Identify the geographic limits of sites in which incised pottery
traditions directly follow Lapita pottery.

You can choose to:
 - print this [[file:maps/Oceania-blank.pdf][pdf version of the map]], mark it up with a pencil, and
   turn in the paper map at class time, or
 - edit this [[file:maps/Oceania-blank.svg][vector graphics version of the map]] with appropriate
   software and turn in the map graphic on Laulima.

** Western and Eastern Micronesia
   :PROPERTIES:
   :ID:       CCB59B44-AB9F-4609-811E-1046C2ECFD98
   :END:

Indicate the geographic regions of Western and Eastern Micronesia and
show the likely routes of dispersal into each region.  

You can choose to:
 - print this [[file:maps/Oceania-blank.pdf][pdf version of the map]], mark it up with a pencil, and
   turn in the paper map at class time, or
 - edit this [[file:maps/Oceania-blank.svg][vector graphics version of the map]] with appropriate
   software and turn in the map graphic on Laulima.
* Class Participation
  :PROPERTIES:
  :ID:       CB24D8B4-60E8-41EA-AE33-9B9A9761B58E
  :END:
You can earn a maximum of 1 point a week by attending all of the class
sessions during the week and /contributing meaningfully/ to the
discussion.  One way to participate meaningfully is to contribute
definitions to the [[id:BC344281-5A95-4E17-96B7-F0E3AD14FCB8][list of long and/or obscure words]] in the textbook.

  - If you miss a class session you cannot earn a class participation
    point for that week
  - Your instructor solely determines whether or not you contributed
    meaningfully to the discussion


* Long and/or Obscure Words
  :PROPERTIES:
  :ID:       BC344281-5A95-4E17-96B7-F0E3AD14FCB8
  :END:
The following list includes definitions for unusual words in /On the
Road of the Winds/, organized by chapter.  The list is a class project built up
over the semester.

** Introduction
 - Cyclopean :: A style of construction often applied to walls built
      of large boulders of a size which called for giants to handle
      them and with interstices filled up with small stones.
 - megalith :: Literally, a big stone.  Often applied as a general
      term to monuments which incorporate such stones into their
      construction.
 - in situ :: In its original position.
* Setup for slide shows                                            :noexport:
, #+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:{} arch:headline
, #+OPTIONS: author:t c:nil creator:nil d:(not "LOGBOOK") date:nil
, #+OPTIONS: e:t email:nil f:t inline:t num:t p:nil pri:nil prop:nil
, #+OPTIONS: stat:t tags:t tasks:t tex:t timestamp:t toc:nil todo:nil |:t
#+OPTIONS: html-link-use-abs-url:nil html-postamble:auto
#+OPTIONS: html-preamble:t html-scripts:t html-style:t
#+OPTIONS: html5-fancy:nil tex:t author:t creator:nil date:nil timestamp:t
#+HTML_DOCTYPE: xhtml-strict
#+HTML_CONTAINER: div
#+CREATOR: <a href="http://www.gnu.org/software/emacs/">Emacs</a> 24.5.1 (<a href="http://orgmode.org">Org</a> mode 8.3beta)
#+SETUPFILE: /Users/dk/.emacs.d/src/org-html-themes/setup/theme-readtheorg.setup
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+STARTUP: entitiespretty
#+LATEX_CLASS: latex-presentation
#+LATEX_HEADER: \addbibresource{local.bib}
#+MACRO: center @@latex:\centering @@
#+MACRO: clearpage @@latex:\clearpage @@
#+MACRO: sizefig #+attr_latex: :height 0.8\textheight
#+MACRO: compactitem #+attr_latex: :environment compactitem
#+MACRO: compactdesc #+attr_latex: :environment compactdesc
#+MACRO: red \textcolor{solarized-red}{$1}
#+MACRO: green \textcolor{solarized-green}{$1}
#+MACRO: blue \textcolor{solarized-blue}{$1}
#+MACRO: cyan \textcolor{solarized-cyan}{$1}
#+MACRO: violet \textcolor{solarized-violet}{$1}
#+MACRO: magenta \textcolor{solarized-magenta}{$1}
#+MACRO: orange \textcolor{solarized-orange}{$1}
#+MACRO: yellow \textcolor{solarized-yellow}{$1}

** Source Code                                                     :noexport:

*** Title slide

 This source block is called at the start of each slide show, before
 the first subheading.

 #+name: latex-presentation-title-slide
 #+header: :results latex silent
 #+header: :exports results
 #+begin_src emacs-lisp
   (format "\\thispagestyle{empty}
   \\begin{tikzpicture}[remember picture,overlay]
     \\node [xshift=\\paperwidth/2, yshift=-\\paperheight/2] (mytitlepage) at
     (current page.north west)[rectangle, fill, inner sep=0pt, minimum
     width=\\paperwidth, minimum height=\\paperheight, top
     color=mybgcolor!64, bottom color=mybgcolor]{}; 
     \\draw (0,12mm)
       node [right, text width=110mm, anchor=west] {%%\\flushright
         \\color{myfontcolor} \\huge \\myhead};
     \\draw (\\paperwidth/2.5,-\\paperheight/2)
       node [right, text width=150mm, anchor=west] {\\color{myfontcolor} \\large
         \\myauthor};
     \\draw (\\paperwidth/2.5,-\\paperheight/2-5 mm)
       node [right, text width=150mm, anchor=west] {\\color{myfontcolor} \\large
         \\myuni};
   \\end{tikzpicture}%%
   \\clearpage")
 #+end_src


*** Presentation class

 #+name: latex-presentation
 #+header: :results silent
 #+BEGIN_SRC emacs-lisp
   (require 'ox-latex)
   (add-to-list 'org-latex-packages-alist '("pdfpagemode=FullScreen,colorlinks=true,urlcolor=solarized-yellow,linkcolor=solarized-yellow,citecolor=solarized-yellow" "hyperref"))
   (add-to-list 'org-latex-packages-alist '("" "newunicodechar"))
   (add-to-list 'org-latex-packages-alist '("AUTO" "inputenc"))
   (add-to-list 'org-latex-packages-alist '("notes,notetype=endonly,backend=bibtex8" "biblatex-chicago"))
   (add-to-list 'org-latex-packages-alist '("" "endnotes"))
   (add-to-list 'org-latex-packages-alist '("" "booktabs"))
   (add-to-list 'org-latex-packages-alist '("" "paralist"))
   (add-to-list 'org-latex-packages-alist '("" "tabularx"))
   (add-to-list 'org-latex-packages-alist '("" "tikz"))
   (add-to-list 'org-latex-packages-alist '("" "media9"))
   (add-to-list 'org-latex-packages-alist '("" "graphicx"))
   (add-to-list 'org-latex-packages-alist '("" "xcolor-solarized"))
   (add-to-list 'org-latex-packages-alist '("" "bm"))
   (add-to-list 'org-latex-packages-alist '("" "tocstyle"))
   (add-to-list 'org-latex-packages-alist '("" "titlesec"))
   (add-to-list 'org-latex-packages-alist '("" "scrpage2"))
   (add-to-list 'org-latex-packages-alist '("includeheadfoot, top=3.5mm, bottom=3.5mm, left=5.5mm, right=5.5mm, headsep=6.5mm, footskip=8.5mm" "geometry"))
   (add-to-list 'org-latex-packages-alist '("" "calc"))
   (add-to-list 'org-latex-packages-alist '("" "xcolor"))
   (add-to-list 'org-latex-packages-alist '("" "microtype"))
   (add-to-list 'org-latex-packages-alist '("american" "babel"))
   (add-to-list 'org-latex-packages-alist '("bitstream-charter" "mathdesign"))
   (add-to-list 'org-latex-packages-alist '("T1" "fontenc"))
   (setq org-export-latex-hyperref-format "\\ref{%s}")
   (setq org-latex-tables-booktabs t)
   (setq org-latex-remove-logfiles nil)
   (add-to-list 'org-latex-classes
                '("latex-presentation"
                  "\\documentclass[x11names,paper=128mm:96mm,fontsize=11pt,pagesize,parskip=half-,numbers=noendperiod,captions=nooneline]{scrartcl}
                         [NO-DEFAULT-PACKAGES]
                         [PACKAGES]
                         [EXTRA]
% missing Welsh coverage
\\newunicodechar{Ŵ}{\\^W}
\\newunicodechar{ŵ}{\\^w}
\\newunicodechar{Ŷ}{\\^Y}
\\newunicodechar{ŷ}{\\^y}

% Latin vowels with prosodic marks    
\\newunicodechar{Ĕ}{\\u{E}}
\\newunicodechar{ĕ}{\\u{e}}
\\newunicodechar{Ĭ}{\\u{I}}
\\newunicodechar{ĭ}{\\u{\\i}}
\\newunicodechar{Ŏ}{\\u{O}}
\\newunicodechar{ŏ}{\\u{o}}
\\newunicodechar{Ŭ}{\\u{U}}
\\newunicodechar{ŭ}{\\u{u}}
\\newunicodechar{Ā}{\\=A}
\\newunicodechar{ā}{\\=a}
\\newunicodechar{Ē}{\\=E}
\\newunicodechar{ē}{\\=e}
\\newunicodechar{Ī}{\\=I}
\\newunicodechar{ī}{\\={\\i}}
\\newunicodechar{Ō}{\\=O}
\\newunicodechar{ō}{\\=o}
\\newunicodechar{Ū}{\\=U}
\\newunicodechar{ū}{\\=u}
\\newunicodechar{Ȳ}{\\=Y}
\\newunicodechar{ȳ}{\\=y}
   \\colorlet{mybgcolor}{solarized-base2}
   \\colorlet{myfontcolor}{solarized-base1}
   \\let\\footnote=\\endnote
   \\let\\footnotemark=\\endnotemark
   \\let\\footnotetext=\\endnotetext
   \\newcommand{\\rcdatebf}[2]{\\ensuremath{\\mathbf{#1 \\pm #2}}}
   \\newcommand{\\deltac}[1]{\\ensuremath{\\delta^{13}C = #1 \\permil}}

   % page style
   \\pagecolor{solarized-base3}
   \\color{solarized-base00}
   \\pagestyle{scrheadings}% activates pagestyle from scrpage2
   \\clearscrheadfoot% clear head and foot
   \\setkomafont{pageheadfoot}{\\normalfont\\color{myfontcolor}\\sffamily}% setting for page head and foot
   % optical vertical centering of page contents
   \\makeatletter
   \\renewcommand*{\\@textbottom}{\\vskip \\z@ \\@plus 1fil}
   \\newcommand*{\\@texttop}{\\vskip \\z@ \\@plus .5fil}
   \\addtolength{\\parskip}{\\z@\\@plus .25fil}% stretch parskip
   \\makeatother
   \\ihead{% head left
     \\hspace{-2mm}%
     \\begin{tikzpicture}[remember picture,overlay]
     \\node [xshift=\\paperwidth/2,yshift=-\\headheight] (mybar) at
     (current page.north west)[rectangle, fill, inner sep=0pt, minimum
     width=\\paperwidth, minimum height=2\\headheight, top
     color=mybgcolor!64, bottom color=mybgcolor]{};% bar
     \\node[below of=mybar, yshift=3.3mm, rectangle, shade,
     inner sep=0pt, minimum width=128mm, minimum height=1.5mm, top
     color=solarized-base1!50, bottom color=solarized-base3]{};%
     shadow
   \\end{tikzpicture}%
   \\myhead
   }
   % \\newlength{\\footheight}
   \\setlength{\\footheight}{8mm}
   \\addtokomafont{pagefoot}{\\footnotesize}% size for foot
   \\setkomafont{pagenumber}{\\color{myfontcolor}}% white page number
   \\ifoot{% foot left
     \\hspace{-2mm}%
     \\begin{tikzpicture}[remember picture,overlay]
       \\node [xshift=\\paperwidth/2, yshift=\\footheight/2] at (current
       page.south west)[rectangle, fill, inner sep=0pt, minimum
       width=\\paperwidth, minimum height =\\footheight, top
       color=mybgcolor!64, bottom color= mybgcolor]{};% bar
   \\end{tikzpicture}%
   \\myauthor\\ \\raisebox{0.2mm}{$\\bm{\\vert}$}\\ \\myuni }
   \\ofoot[\\pagemark\\hspace{-2mm}]{\\pagemark\\hspace{-2mm}}% foot right (plain pages do also have page numbers)
   \\AtBeginDocument{\\renewcaptionname{american}{\\contentsname}{\\large Outline}}% change name of toc
   \\makeatletter
   \\newtocstyle[noonewithdot]{nodotnopagenumber}{% define tocstyle without dots and page numbers
   \\settocfeature{pagenumberbox}{\\@gobble}%
   }
   \\makeatother

   \\usetocstyle{nodotnopagenumber}

   \\makeatletter
   \\newcommand{\\myhead}{\\@title}
   \\newcommand{\\myauthor}{\\@author}
   \\makeatother
   \\newcommand{\\slidehead}[1]{\\subsubsection*{#1}}"
                  ("\\clearpage\\slidehead{%s}" . "\\clearpage\\slidehead{%s}")
                  ("\\clearpage\\slidehead{%s}" . "\\clearpage\\slidehead{%s}")
                  ("\\clearpage\\slidehead{%s}" . "\\clearpage\\slidehead{%s}")
                  ("\\clearpage\\slidehead{%s}" . "\\clearpage\\slidehead{%s}")
                  ("\\clearpage\\slidehead{%s}" . "\\clearpage\\slidehead{%s}")))
 #+END_SRC

*** Audio link                                                     :noexport:
The audio link is set up to export an invisible audio link into a pdf
file for viewing with Adobe Acrobat (doesn't work in Skim).  It is set
up to playback the audio file in the link when the pdf page is first
visible, starting always from the beginning.  There are no controls
for playback.

A playback window shows progress.  It appears at the top right corner
of the slide.

Its typical use is at the beginning or end of a slide.


#+name: audio-link
#+header: :results silent :exports none
#+begin_src emacs-lisp
(org-add-link-type
 "audio" nil
 (lambda (path desc format)
   (cond
     ((eq format 'latex)
      (format "\\includemedia[
  addresource=%s,
  width=1cm,
  height=0.5cm,
  transparent,
  windowed=@tr,
  activate=pagevisible,
  noplaybutton,
  flashvars={
    source=%s
   &autoPlay=true
  },
]{}{APlayer.swf}" path path)))))
#+end_src

*** TODO Audio link insertion function


This would be nice to have, but org-insert-link is crazy complicated
and looks difficult to modify.

What I'm trying to do is run (org-insert-link) as if it had been
called with C-u.

#+name: audio-link-insert
#+begin_src emacs-lisp
(defun td-org-insert-audio-link ()
  (interactive)
  (org-insert-link t)
  (while (search-forward "file:" nil nil -1)
    (replace-match "audio:" t t "file")))
#+end_src

#+results: audio-link-insert
: td-org-insert-audio-link

*** Remove spaces

#+name: no-line-spaces-in-org-outline
#+begin_src emacs-lisp :results silent
(setq org-cycle-separator-lines 0)
#+end_src


** Local variables                                                 :noexport:

# Local Variables: 
# eval: (require 'ox-latex)
# org-fontify-quote-and-verse-blocks: t 
# org-hide-macro-markers: t
# org-latex-title-command: ""
# eval: (and (fboundp 'org-sbe) (not (fboundp 'sbe)) (fset 'sbe 'org-sbe))
# org-entities-user: nil
# eval: (sbe "no-line-spaces-in-org-outline")
# eval: (sbe "user-entities")
# eval: (sbe "ebib-link")
# eval: (sbe "change-cite-link")
# eval: (sbe "ngz-nbsp")
# eval: (sbe "define-standard-biblatex-commands")
# eval: (sbe "define-biblatex-multicite-link")
# org-latex-packages-alist: nil
# eval: (sbe "latex-presentation")
# eval: (sbe "set-pdf-process-bibtex")
# eval: (sbe "tsd-latex-filter-all-cites")
# eval: (sbe "rpr-filter-headline-tags")
# eval: (add-to-list 'org-export-filter-headline-functions 'tsd-filter-headline-tags)
# eval: (sbe "rpr-filter-section-star")
# eval: (sbe "jk-keywords")
# eval: (sbe "es-small-caps")
# eval: (sbe "tsd-xref")
# eval: (sbe "audio-link")
# End:

* Footnotes

[fn:1] See http://en.wikisource.org/wiki/The_Fixation_of_Belief. 









[-- Attachment #3: Type: text/plain, Size: 41 bytes --]



-- 
Thomas S. Dye
http://www.tsdye.com

^ permalink raw reply	[relevance 2%]

* Re: Error when exporting LaTeX
  @ 2015-06-24 12:45  8% ` Peter Davis
  0 siblings, 0 replies; 200+ results
From: Peter Davis @ 2015-06-24 12:45 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 491 bytes --]

Peter Davis <pfd@pfdstudio.com> writes:

> I'm writing a fairly simple document with some #+BEGIN_SRC/#+END_SRC
> blocks, and when I try to export to LaTeX/PDF, I get:
>
> org-latex-src-block: Wrong type argument: stringp, nil
>
> Does this ring any bells? I can try to cobble together a "neutralized"
> sample to reproduce the problem, but I thought I'd see if anyone
> recognized it.

Ok, here's a sample file and image that reproduces the problem. Any help
appreciated.

Thank you.

-pd


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: org file that triggers "wrong type argument" error --]
[-- Type: text/x-org, Size: 2923 bytes --]

#+STARTUP: showeverything logdone
#+options: num:nil
#+OPTIONS:   H:5 num:t \n:nil @:t ::t |:t ^:nil -:t f:t *:t <:t
#+LaTeX_CLASS: koma-article
#+LaTeX_HEADER: \usepackage{listings}
#+LATEX_HEADER: \setlength{\parskip}{2ex plus 4pt minus 2pt}
#+LATEX_HEADER: \setlength{\parindent}{0pt}
#+LATEX_HEADER: \renewcommand{\baselinestretch}{1.0}
#+LATEX_HEADER: \setlength{\topsep}{-10pt}
#+LATEX_HEADER: \setlength{\partopsep}{0pt}
#+LaTeX_HEADER: \usepackage{xcolor}
#+LaTeX_HEADER: \lstset{
#+LaTeX_HEADER:     basicstyle=\ttfamily,
#+LaTeX_HEADER:     breaklines=true,
#+LaTeX_HEADER:     prebreak=\mbox{\ensuremath{\color{red}\hookleftarrow}},
#+LaTeX_HEADER:     postbreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\color{red}\hookrightarrow\space}},
#+LaTeX_HEADER:     columns=fullflexible,
#+LaTeX_HEADER:     keepspaces=true
#+LaTeX_HEADER: }
#+LaTeX_CLASS_OPTIONS: [article,letterpaper,times,12pt,listings-bw,microtype]
#+author: Peter Davis
#+title: LaTeX export issue

* Overview

Many applications using the XYZCo API will follow a sequence of operations like this:

** User logs in, establishing identity and access privileges

The login page is invoked via an http request, such as:

#+BEGIN_SRC js
GET http://local.xyzco.com:3000/sample/login
#+END_SRC

In the Sample App, this results in a page showing four buttons:

[[./pd-logo-jelly-small.gif]]

** Login with XYZ

If the user selects "Login with XYZ", the Sample App invokes this URL:

#+BEGIN_SRC
GET http://local.xyzco.com:3000/sample/auth/xyz
#+END_SRC

The response, 302, results in a redirect to a new page prompting for username and password is presented[1]:

#+BEGIN_SRC js
GET http://sandbox.api.xyzco.com:8080/openid-connect/v2/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocal.xyzco.com%3A3000%2Fsample%2Fauth%2Fxyz%2Fcallback&scope=openid&client_id=152ced50-1369-4b19-8b26-8f3d5d9bfd6a.xyzco.com
#+END_SRC

[[./pd-logo-jelly-small.gif]]

Entering a username and password here results in this request:

#+BEGIN_SRC js
POST http://sandbox.api.xyzco.com:8080/openid-connect/j_spring_security_check?response_type=code&redirect_uri=http%3A%2F%2Flocal.xyzco.com%3A3000%2Fsample%2Fauth%2Fxyz%2Fcallback&scope=openid&client_id=152ced50-1369-4b19-8b26-8f3d5d9bfd6a.xyzco.com
#+END_SRC

[[./pd-logo-jelly-small.gif]]

** The application provides security information (e.g., OAuth2 token) to enable access to information

#+BEGIN_SRC js
GET http://sandbox.api.xyzco.com:8080/openid-connect/v2/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocal.xyzco.com%3A3000%2Fsample%2Fauth%2Fxyz%2Fcallback&scope=openid&client_id=152ced50-1369-4b19-8b26-8f3d5d9bfd6a.xyzco.com
#+END_SRC

#+BEGIN_SRC js
GET http://local.xyzco.com:3000/sample/auth/xyz/callback?code=eyJhbGciOiLlif_vla6jwjA ...
#+END_SRC

From this point, the application can present other options to the user.

[1] If the user is not already logged in, he or she will see the login page

[-- Attachment #3: sample image for use with error file --]
[-- Type: image/gif, Size: 13395 bytes --]

^ permalink raw reply	[relevance 8%]

* Re: org-mode, tikz and beamer
  @ 2015-05-21 20:33  6%   ` cédric ody
  0 siblings, 0 replies; 200+ results
From: cédric ody @ 2015-05-21 20:33 UTC (permalink / raw)
  To: Suvayu Ali; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 2959 bytes --]

Thank you for your answer.

Here is the shell script (many comments are in english except the
beginning) and the org file I use. To see how I call it, you can have
a look at the enclosed Makefile. Note that it uses specific
configurations files as well tex macros so it won't work without these
files. I can prepare a short example which generates the tex and pdf
files if needed. The script probably gives for now a good idea. You
can also look at the enclosed generated tex file to see how the tikz
language.

Basically, the shell script looks recursively into the org file and
creates nodes for the tikz headline mindmaps. Thus, there are parent
nodes and children nodes.

During that excursion, two kinds of files are created: the "tree"
files and the "contents" files.

The first ones are tex files with tikz mindmaps that must be inserted
at specific locations at the final latex compilation step. One tree
file contains the parent node with all the children files.

The "contents" files are org files and are converted into tex files
via the org-mode export command in a batch way. In the shell script,
hyperlinks are added to these newly converted tex files.

At the end, the assembly of all these files is done before compiling.

Numbering of sections through the recursive call is important so that
links work properly as you notice. Links allow one to go back and
forth the document. To go back, the idea is to click on the headline.
If a node exists without content, the links sends you the beginning of
the file or something like that.

Cheers,

Cédric


2015-05-21 20:02 UTC+02:00, Suvayu Ali <fatkasuvayu+linux@gmail.com>:
> On Thu, May 21, 2015 at 04:40:33PM +0200, cédric ody wrote:
>> Dear org-mode users,
>>
>> I have used org-mode for some months now. I find it very useful. I
>> have recently used it to prepare mathematic teaching lessons using the
>> beamer exporter.
>>
>> I wanted to combine org-mode and tikz latex's package from latex In
>> order to insert some kind of mind-mapping from the headlines between
>> the main parts of the lesson. I enclose an example so that you can see
>> what I am talking about. Note that you can move forth and back through
>> the presentation with hyperlinks. Note also only the chapter "Droites
>> dans le plan" is filled so most of links fail.
>
> Some of the links in that chapter are not working properly I think, but
> otherwise it's a very impressive start!  If you post your current shell
> script with the Org file, I think others can suggest what is and is not
> possible.
>
> To put it in more words, we don't know what you are thinking.  If we can
> see the Org source and the shell script, it is easier to understand how
> you map Org elements to beamer/tikz environments.
>
> I think you have started a very interesting project!
>
> Cheers,
>
> --
> Suvayu
>
> Open source is the future. It sets us free.
>
>

[-- Attachment #2: org2tex.sh --]
[-- Type: application/x-sh, Size: 10755 bytes --]

[-- Attachment #3: coursP.org --]
[-- Type: application/octet-stream, Size: 11678 bytes --]

Première STL 
* Le second degré :noexport:
* Étude de fonctions :noexport:
* Dérivation :noexport:
* Fonctions circulaires :noexport:
* Suites numériques :noexport:
** Introduction
*** Exemples de suites 
- Suite "identité"
$$1,2,3,\cdots,n$$
- Suite nulle
$$0,0,0,\cdots$$
- Suite des nombres pairs
$$2,4,6,8,10,12,14\cdots$$
- Suite des nombres impairs
$$1,3,5,7,9,11,13\cdots$$
*** Suites, augmentations,réductions, soldes
** Définitions et notations
#+begin_defi
Une *suite numérique* est une fonction de l'ensemble des nombres
entiers (N) vers l'ensemble des nombres réels (R). Il s'agit en fait
d'une liste de nombres consécutifs indicés.
#+end_defi
On utilise souvent la notation $(u_n)$ ou $(v_n)$ pour désigner une
suite. Pour la suite $(u_n)$, le nombre $u_0$ est appelé terme de rang
0, le nombre $u_1$ terme de rang 1,  le nombre $u_n$  terme de rang
$n$, ... On utilise également indice à la place de rang.
** Suites arithmétiques et géométriques (1)
%%%
#+begin_defi 
Une suite  *arithmétique* est une suite numérique dont chaque
terme s'obtient en *additionnant*  au précédent terme un nombre *constant*
(généralement noté  $r$). Mathématiquement dit, on a
$$ u_{n+1}=u_n+  r .$$
#+end_defi
%%%
#+begin_defi 
Une suite  *géométrique*  est une suite numérique dont chaque
terme s'obtient en *multipliant*  le précédent terme par un nombre *constant*
(généralement notée $q$) appelé *raison* de la suite. Mathématiquement dit, on a
$$ v_{n+1}=v_n q. $$
#+end_defi
** Suites arithmétiques et géométriques (2)
#+begin_prop 
Une suite $(u_n)$ est *arithmétique* lorsqu'on peut écrire 
$$ u_n=u_0+n  r .$$
#+end_prop
#+begin_prop 
Une suite $(v_n)$ est *géométrique* lorsqu'on peut écrire 
$$ v_n=v_0 q^n \quad \text{ou encore} \quad v_n=v_1 q^{n-1}.$$
#+end_prop
** Exemple de représentation graphique
\begin{center}
\begin{tikzpicture}[x=1.cm,y=0.4cm,style=thick]
% \draw [color=cqcqcq,dash pattern=on 3pt off 3pt, xstep=1.5cm,ystep=1.5cm] (0,0) grid (4,4);
\draw[->,color=black] (0,0) -- (4.5,0) node[right]{$n$}; 
\draw[->,color=black] (0,0) -- (0,17.5) node[above]{$u_n$};
\foreach \x in {0,1,2,3,4}
\draw[shift={(\x,0)},color=black,style=very thick] (0pt,2pt) -- (0pt,-2pt) node[below] {\scriptsize $\x$};
\foreach \x in {1,2,3,4}
\fill [color=qqqqff] (\x,\x*\x) circle (1.5pt) node[right] {\scriptsize \bf $u_\x$} ;
\foreach \y in {0,1,4,9,16}
\draw[shift={(0,\y)},color=black,style=very thick] (2pt,0pt) -- (-2pt,0pt)  node[left] {\scriptsize $\y$};;
\end{tikzpicture}
\end{center}
** Comment fabriquer une suite numérique?
*** On donne explicitement l'expression de $u_n$ en fonction de $n$
On l'a déjà vu. Dans le cas d'une suite arithmétique, connaissant
$u_0$ et le nombre $r$, on écrit
$$ u_n=u_0+n \times r. $$
De même, pour une suite géométrique, on a l'expression de $v_n$ en
fonction de la raison $q$ et de l'entier $n$
$$ v_n=v_0 q^n. $$
*** On utilise une relation dite de récurrence
On établit une relation entre deux rangs consécutifs, par exemple,
entre les termes de rang $n$ et $n+1$. Par exemple, on écrit
$$u_{n+1}=u_{n}+4$$
ou encore
$$v_{n+1}=v_{n} \times4.$$
** Limite d'une suite géométrique
- Cas où $q=1$
- Cas où $q>1$
- Cas où $q<1$

* Statistique descriptive 
** Compréhension du titre
- Statistiques
- Descriptives
** Organisation-répartition de données 
- Données "brutes"
- Données par effectifs - Effectifs et fréquences
$$f_i=\frac{n_i}{n}.$$
- Synthèse de données en classes
Centre de la classe $[a_i,b_i[$
$$c_i=\frac{a_i,b_i}{2}.$$
** Faire des statistiques sur ces données!
*** Statistiques examen février
*** Question de tendance! centrale!
- Tendance centrale
- Moyenne
- Médiane
*** Estimer la cohérence de ces valeurs "centrales"
- Quantification de la précision
- Dispersion
*** La caldoche, un outil qu'il faut savoir utiliser!
** Indicateurs de tendance centrale
*** Moyenne (arithmétique)
#+begin_defi
La moyenne arithmétique de $n$ nombres $x_1,x_2,\cdots,x_n$ est
$$\overline{x}=\frac{x_1+x_2+\cdots+x_n}{n}.$$
On peut écrire cette moyenne en utilisant le symbole $\Sigma$ selon
$$\overline{x}=\frac{1}{n}\sum_{i=1}^{n} x_i.$$
#+end_defi
*** Autres moyennes
%%%
- Lorsqu'on travaille avec $p$ données $x_1,x_2,\cdots,x_p$ dont on connait les effectifs $n_1,n_2,\cdots,n_p$
$$\overline{x}=\frac{n_1 x_1+n_2 x_2+\cdots+n_p x_p}{n}.$$
\medskip
- Si on utilise la notation $\Sigma$, on écrit
$$\overline{x}=\frac{1}{n}\sum_{i=1}^{p} n_i x_i.$$
%%%
- Lorsqu'on travaille avec $p$ classes (intervalles)
  $[a_1,b_1[,[a_2,b_2[,\cdots,[a_p,b_p[$ dont on connait les effectifs
  $n_1,n_2,\cdots,n_p$, la moyenne arithmétique se calcule (de façon
  approchée) en   utilisants les centres des classes
$$\overline{x}=\frac{n_1 c_1+n_2 c_2+\cdots+n_p c_p}{n}.$$
\medskip
- Si on utilise la notation $\Sigma$, on écrit
$$\overline{x}=\frac{1}{n}\sum_{i=1}^{p} n_i c_i.$$

*** La médiane - Moit'-moit'!
#+begin_defi
Dans une série statistique de $n$ données *classées* (par ordre croissant
ou décroissant), la *médiane* notée $Me$ est:
- la donnée du milieu si $n$ est impair
- la demi-somme des deux données du milieu, si $n$ est pair 
#+end_defi
- La médiane est un indicateur différent de la moyenne. Elle nous dit
  que 50\% des données sont inférieures à la médiane et donc 50\% lui
  sont supérieures.
** Indicateurs-caractéristiques de dispersion
*** Introduction - Écart moyen
%%%
- Prenons une série de données. Calculons l'écart moyen défini comme
$$\frac{1}{n} \left[ (x_1-\overline{x})+(x_2-\overline{x})+\cdots+(x_n-\overline{x})\right]$$
- Aïe, on trouve que cet écart vaut ...?
%%%
- Deux alternatives:
-- L'écart moyen absolu
$$\frac{1}{n} \left[ |x_1-\overline{x}|+|x_2-\overline{x}|+\cdots+|x_n-\overline{x}|\right]$$
-- L'écart moyen au carré
$$\frac{1}{n} \left[ (x_1-\overline{x})^2+(x_2-\overline{x})^2+\cdots+(x_n-\overline{x})^2\right]$$
*** Variances, écarts-types
%%%
- L'écart moyen au carré est sympathique pour faire des calculs analytiques ou théoriques! On garde cet écart mais on le renomme en variance.
#+begin_defi
La variance vaut donc
$$V=\frac{1}{n} \left[ (x_1-\overline{x})^2+(x_2-\overline{x})^2+\cdots+(x_n-\overline{x})^2\right].$$
#+end_defi
%%%
- Comme la variance est un carré, il faut prendre la racine pour avoir des unités cohérentes. On définit alors l'écart-type $\sigma$.
#+begin_defi
L'écart-type se calcule donc selon
$$\sigma=\sqrt{V}.$$
#+end_defi
%%%
- Formules selon le type de données
|               | Variance                                                                                                        |
| brutes        | $V=\frac{1}{n} \left[ (x_1-\overline{x})^2+(x_2-\overline{x})^2+\cdots+(x_n-\overline{x})^2\right]$             |
| par effectifs | $V=\frac{1}{n} \left[ n_1 (x_1-\overline{x})^2+n_2 (x_2-\overline{x})^2+\cdots+n_p (x_p-\overline{x})^2\right]$ |
| par classes   | $V=\frac{1}{n} \left[ n_1 (c_1-\overline{x})^2+n_2 (c_2-\overline{x})^2+\cdots+n_p (c_p-\overline{x})^2\right]$ |
- Formules équivalentes (à démontrer!!)
|             | Variance                                                           |
| brute       | $V=\frac{x_1^2+x_2^2+\cdots+x_n^2}{n}-\overline{x}^2$              |
| par effectifs | $V=\frac{n_1 x_1^2+n_2 x_2^2+\cdots+n_p x_p^2}{n}-\overline{x}^2$  |
| par classes | $V=\frac{n_1 c_1^2+n_2 c_2^2+\cdots+n_p c_p^2}{n}-\overline{x}^2$ |

*** Quartiles et écarts interquartiles
- De façon analogue à la médiane, on classe les données en parties de
  mêmes effectifs. Pour les quartiles, on classe les données en quatre
  parties de mêmes effectifs. On obtient alors trois *quartiles* comme
  valeurs séparant chaque partie. On les note $Q_1,Q_2$ et $Q_3$.
- On peut parler de l'*intervalle interquartile* $[Q_1,Q_3[$. Cet intervalle contient 50\% des données
  de la série statistique étudiée.
- On peut également définir l'indicateur de dispersion appelé *écart
  interquartile* défini comme $Q_3-Q_1$.
*** Diagrammes en boites
* Probabilités 
** Rappels de seconde
- Arbres pondérés
- Épreuves
- Variable aléatoire
- Histogramme - Histogramme cumulé
- Règles de calcul
#+begin_prop
La probabilité d'un événement est la somme des probabilités des
événements élémentaires qui le constituent.
#+end_prop
** Schéma de Bernoulli
*** Qui est Bernoulli?! Pourquoi son nom?
*** Épreuve de Bernoulli: succès ou échec!
#+begin_defi
Une *épreuve de Bernoulli de paramètre* $p$ est une épreuve aléatoire
comportant deux issues possibles. Le paramètre $p$ est un nombre réel
compris entre $0$ et $1$.
#+end_defi
- En général, la probabilité du succès est $p$ tandis que la
  probabilité de l'échec est $1-p$. L'échec est l'événement contraire
  du succès!
- On schématise l'épreuve de Bernoulli par deux branches!
*** Succession d'épreuves de Bernoulli
#+begin_defi
Un *schéma de Bernoulli* de paramètres $n$ et $p$ est une épreuve
aléatoire consistant à répéter $n$ fois, de façon identique et
indépendante, une épréuve de Bernoulli de paramètre $p$.
#+end_defi
- On schématise un schéma de Bernoulli par un arbre.
*** Nombre de succès dans un schéma de Bernoulli
*** Calcul de probabilités dans un schéma de Bernoulli
#+begin_prop
- La probabilité d'une issue donnée est le produit des probabilités sur le
chemin conduisant à cette issue.
#+end_prop

** Loi binomiale
*** Variables en analyse et en probabilités
- Vous connaissez les variables qu'on utilise avec les fonctions. Par
  exemple, la variable $x$ est utilée dans $f(x)$. On étudie le
  comportement de la fonction en fonction de la variable $x$ (valeurs,
  variations). On
  choisit $x$ dans un intervalle (cohérent).
\medskip
- En probabilité, c'est différent. Les épreuves sont aléatoires. On ne
  peut pas prendre n'importe quelle valeur pour la variable. Il faut
  qu'elle ait un sens. Ce qu'on cherche c'est la probabilité pour que
  cette variable ait telle ou telle valeur.
*** Variable aléatoire associée au nombre de succès
| $k$      | $0$       | $1$         | $2$           | $3$         |     4 |
| $P(X=k)$ | $(1-p)^4$ | $4p(1-p)^3$ | $6p^2(1-p)^2$ | $4p^3(1-p)$ | $p^4$ |
*** Définition - propriétés
#+begin_defi
La *loi binomiale* de paramètres $n$ et $p$ notée $\mathcal{B}(n,p)$
est la loi de probabilité de la variable aléatoire $X$ associée au
nombre de succès dans la répétition de $n$ épreuves de Bernoulli de
paramètre $p$.
#+end_defi
*** Pourquoi binomiale?!
%%%
- Le binôme de Newton
%%%
#+begin_prop
Pour la variable aléatoire $X$ qui suit la loi binomiale
$\mathcal{B}(n,p)$, on a pour entier $k$ compris entre 0 et $n$ et
décrivant le nombre de succès,
$$P(X=k)=(n k)p^k (1-p)^{n-k}.$$
#+end_prop
*** Représentation graphique
*** Espérance, variance et écart-type

*** Champ d'intervention de la loi binomiale :noexport:
* Produit scalaire dans le plan :noexport:
** Rappels sur les vecteurs
*** Coordonnées d'un vecteur
*** Égalité de deux vecteurs
** Compléments sur les vecteurs
*** Norme d'un vecteur
*** Cosinus d'une mesure d'angle de vecteurs
** Définition du produit scalaire 
*** Définition
*** Expression avec le projeté orthogonal
*** Expression analytique en repère orthonormé
** Commutativité et bilinéarité du produit scalaire
** Orthogonalité et produit scalaire
* Nombres complexes :noexport:


[-- Attachment #4: coursP.tex --]
[-- Type: application/x-tex, Size: 23283 bytes --]

^ permalink raw reply	[relevance 6%]

* Re: Resume: Squeezing lines tighter in LaTeX output?
  2015-04-18  2:20 13%     ` Peter Davis
  2015-04-18  7:02  7%       ` Marcin Borkowski
@ 2015-04-20  8:23  0%       ` Eric S Fraga
  1 sibling, 0 replies; 200+ results
From: Eric S Fraga @ 2015-04-20  8:23 UTC (permalink / raw)
  To: Peter Davis; +Cc: emacs-orgmode

On Friday, 17 Apr 2015 at 22:20, Peter Davis wrote:
> Thanks. I've had some success with these headers:

[...]

> #+LATEX_HEADER: \setlength{\headsep}{0pt}
> #+LATEX_HEADER: \setlength{\topskip}{0pt}
> #+LATEX_HEADER: \setlength{\topmargin}{0pt}
> #+LATEX_HEADER: \setlength{\topsep}{-10pt}

[...]

You may wish to consider using the geometry package to set up the page
instead of settings lengths directly.
-- 
: Eric S Fraga (0xFFFCF67D), Emacs 24.4.1, Org release_8.3beta-820-gd92ef9

^ permalink raw reply	[relevance 0%]

* Re: Resume: Squeezing lines tighter in LaTeX output?
  2015-04-18  2:20 13%     ` Peter Davis
@ 2015-04-18  7:02  7%       ` Marcin Borkowski
  2015-04-20  8:23  0%       ` Eric S Fraga
  1 sibling, 0 replies; 200+ results
From: Marcin Borkowski @ 2015-04-18  7:02 UTC (permalink / raw)
  To: emacs-orgmode


On 2015-04-18, at 04:20, Peter Davis <pfd@pfdstudio.com> wrote:

> Thanks. I've had some success with these headers:
>
> #+LATEX_HEADER: \setlength{\parskip}{0pt}
> #+LATEX_HEADER: \setlength{\parsep}{6pt}
> #+LATEX_HEADER: \setlength{\headsep}{0pt}
> #+LATEX_HEADER: \setlength{\topskip}{0pt}
> #+LATEX_HEADER: \setlength{\topmargin}{0pt}
> #+LATEX_HEADER: \setlength{\topsep}{-10pt}
> #+LATEX_HEADER: \setlength{\partopsep}{0pt}
> #+LATEX_HEADER: \linespread{0.75}
> #+LATEX_HEADER: \usepackage{enumitem}
> #+LATEX_HEADER: \setlist{nolistsep}
> #+LATEX_HEADER: \usepackage[compact]{titlesec}
> #+LATEX_HEADER: \titlespacing{\section}{0pt}{1ex}{1ex}
> #+LATEX_HEADER: \titlespacing{\subsection}{0pt}{1ex}{1ex}
> #+LATEX_HEADER: \titlespacing{\subsubsection}{0pt}{1ex}{1ex}

Notice that you set up some low-level TeX dimensions, which is probably
not a very good idea.  I would advise not to set manually any dimension
unless you know exactly what you're doing.  For instance, setting
\topskip to 0pt is seldom a good idea.  (You will butcher the
consistency of spacing - more precisely, the top margin will be "wobbly"
then - for no gain in "less spacing".)  For manipulating page-related
dimensions, the "canonical" way nowadays is to use the geometry package.
Also, negative \topsep looks strange, though I'm not knowledgable enough
about LaTeX inner workings to understand everything you do here.

> In fact, the spacing's a little too tight now. I'll have to play with 
> the settings some more. Right now, the paragraph spacing between bullet 
> items is tighter than the spacing between lines within a paragraph.

No idea why.  You might ask on TeX.SE, or just start with deleting evry
setting you are not sure what it does and see what happens.

Hth,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University

^ permalink raw reply	[relevance 7%]

* Re: Resume: Squeezing lines tighter in LaTeX output?
  @ 2015-04-18  2:20 13%     ` Peter Davis
  2015-04-18  7:02  7%       ` Marcin Borkowski
  2015-04-20  8:23  0%       ` Eric S Fraga
  0 siblings, 2 replies; 200+ results
From: Peter Davis @ 2015-04-18  2:20 UTC (permalink / raw)
  To: emacs-orgmode


Thanks. I've had some success with these headers:

#+LATEX_HEADER: \setlength{\parskip}{0pt}
#+LATEX_HEADER: \setlength{\parsep}{6pt}
#+LATEX_HEADER: \setlength{\headsep}{0pt}
#+LATEX_HEADER: \setlength{\topskip}{0pt}
#+LATEX_HEADER: \setlength{\topmargin}{0pt}
#+LATEX_HEADER: \setlength{\topsep}{-10pt}
#+LATEX_HEADER: \setlength{\partopsep}{0pt}
#+LATEX_HEADER: \linespread{0.75}
#+LATEX_HEADER: \usepackage{enumitem}
#+LATEX_HEADER: \setlist{nolistsep}
#+LATEX_HEADER: \usepackage[compact]{titlesec}
#+LATEX_HEADER: \titlespacing{\section}{0pt}{1ex}{1ex}
#+LATEX_HEADER: \titlespacing{\subsection}{0pt}{1ex}{1ex}
#+LATEX_HEADER: \titlespacing{\subsubsection}{0pt}{1ex}{1ex}

In fact, the spacing's a little too tight now. I'll have to play with 
the settings some more. Right now, the paragraph spacing between bullet 
items is tighter than the spacing between lines within a paragraph.

-- 
----
Peter Davis
The Tech Curmudgeon
www.techcurmudgeon.com

^ permalink raw reply	[relevance 13%]

* Re: org-mode to latex, again!
  2015-03-31 10:26  6% org-mode to latex, again! Sharon Kimble
@ 2015-03-31 15:59  0% ` Marcin Borkowski
  0 siblings, 0 replies; 200+ results
From: Marcin Borkowski @ 2015-03-31 15:59 UTC (permalink / raw)
  To: org-mode


On 2015-03-31, at 12:26, Sharon Kimble <boudiccas@skimble.plus.com> wrote:

> I am attempting again to write a latex document with org-mode. The
> org-mode part is no problem, but the latex part is awkward. This is
> the first few line of my org-mode document -
>
> --8<---------------cut here---------------start------------->8---
> #+TITLE:     The history of custard pies.
> #+AUTHOR:    Sharon Kimble
> #+EMAIL:     boudiccas@skimble.plus.com
> #+DATE:      01-04-2015
> #+LATEX:     \usepackage{~/texmf/tex/latex/commonstuff/mysty}
> # #+Latex_Class: mysty
> #+DESCRIPTION:
> #+KEYWORDS:
> #+LANGUAGE:  en
>
> * Blargh
> --8<---------------cut here---------------end--------------->8---
>
> The latex file "mysty" is actually "mysty.sty" and contains all the
> latex files that I want to use, but it doesn't appear to be loading,
> and I can't see why? My idea of having *all* the latex packages in
> one file is so that I hope to be able to have it in its own
> directory and then symlink it to each projects main org-mode file so
> that I would have a known working setup, right from the start!

1. Then, why not put your customizations in a custom LaTeX class (based
on an existing one)?  Currently, you have a package/class mix (see
below).  See clsguide.pdf in your TeX distro for details about how to do
it (see e.g. section "Example: a newsletter class")

2. And no need to symlink it anywhere.  If you have it in e.g.
~/texmf/tex/latex/mystuff/myclass.cls, run mktexlsr (assuming you are on
TeXlive) and then just \usepackage{mypackage} or
\documentclass{myclass}.  It is only necessary to run mktexlsr again in
case of a change in the directory under ~/texmf, so e.g. new files or
filename changes, but not just updating the file itself.

> The first few lines of "mysty.sty" are
>
> --8<---------------cut here---------------start------------->8---
> \NeedsTeXFormat{LaTeX2e}
> \ProvidesClass{mysty}[31-03-2015]

For .sty, this ^^ should be \ProvidesPackage.  Again, see clsguide.pdf.

> \RequirePackage[l2tabu,orthodox]{nag}

Probably a good idea.

> \RequirePackage{fixltx2e}
> \documentclass[a4paper,12pt]{article}
> % \documentclass[a4paper,12pt]{book}
> % \documentclass[a4paper,12pt]{report} 
> % \documentclass[a4paper,12pt]{memoir} NO
> % \documentclass[a4paper,12pt]{scrbook}
> %%\documentclass[a4paper,12pt]{scrreprt}

This should be \LoadClass (or similar, like \LoadClassWithOptions) in
a class file.

> \usepackage{morewrites}
> \usepackage{tocloft}
> \usepackage[stretch=10]{microtype}
> \setlength\parindent{0pt} % sets indent to zero
> \setlength{\parskip}{5pt} % changes vertical space between paragraphs

Tsk, tsk.  What about \usepackage{parskip}?

> \setcounter{tocdepth}{1}
> --8<---------------cut here---------------end--------------->8---
>
> Any ideas please?
>
> Thanks
> Sharon.

Hth,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University

^ permalink raw reply	[relevance 0%]

* org-mode to latex, again!
@ 2015-03-31 10:26  6% Sharon Kimble
  2015-03-31 15:59  0% ` Marcin Borkowski
  0 siblings, 1 reply; 200+ results
From: Sharon Kimble @ 2015-03-31 10:26 UTC (permalink / raw)
  To: org-mode

[-- Attachment #1: Type: text/plain, Size: 2010 bytes --]

I am attempting again to write a latex document with org-mode. The
org-mode part is no problem, but the latex part is awkward. This is
the first few line of my org-mode document -

--8<---------------cut here---------------start------------->8---
#+TITLE:     The history of custard pies.
#+AUTHOR:    Sharon Kimble
#+EMAIL:     boudiccas@skimble.plus.com
#+DATE:      01-04-2015
#+LATEX:     \usepackage{~/texmf/tex/latex/commonstuff/mysty}
# #+Latex_Class: mysty
#+DESCRIPTION:
#+KEYWORDS:
#+LANGUAGE:  en

* Blargh
--8<---------------cut here---------------end--------------->8---

The latex file "mysty" is actually "mysty.sty" and contains all the
latex files that I want to use, but it doesn't appear to be loading,
and I can't see why? My idea of having *all* the latex packages in
one file is so that I hope to be able to have it in its own
directory and then symlink it to each projects main org-mode file so
that I would have a known working setup, right from the start!

The first few lines of "mysty.sty" are

--8<---------------cut here---------------start------------->8---
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{mysty}[31-03-2015]

\RequirePackage[l2tabu,orthodox]{nag}
\RequirePackage{fixltx2e}
\documentclass[a4paper,12pt]{article}
% \documentclass[a4paper,12pt]{book}
% \documentclass[a4paper,12pt]{report} 
% \documentclass[a4paper,12pt]{memoir} NO
% \documentclass[a4paper,12pt]{scrbook}
%%\documentclass[a4paper,12pt]{scrreprt}
\usepackage{morewrites}
\usepackage{tocloft}
\usepackage[stretch=10]{microtype}
\setlength\parindent{0pt} % sets indent to zero
\setlength{\parskip}{5pt} % changes vertical space between paragraphs
\setcounter{tocdepth}{1}
--8<---------------cut here---------------end--------------->8---

Any ideas please?

Thanks
Sharon.
-- 
A taste of linux = http://www.sharons.org.uk
my git repo = https://bitbucket.org/boudiccas/dots
TGmeds = http://www.tgmeds.org.uk
Debian testing, fluxbox 1.3.7, emacs 24.4.1.0

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[relevance 6%]

* error in make doc
@ 2015-01-06 12:58  4% Andreas Leha
  0 siblings, 0 replies; 200+ results
From: Andreas Leha @ 2015-01-06 12:58 UTC (permalink / raw)
  To: emacs-orgmode

Hi all,

I am on commit 9231460ac02a6ded0d6b198bb4a3dcc44968147a and I see an
error when running 'make doc'.

The output is below.

Thanks,
Andreas


PS: The output of 'make doc'
--8<---------------cut here---------------start------------->8---
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C doc info
make[1]: Nothing to be done for `info'.
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C doc html
make[1]: Nothing to be done for `html'.
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C doc pdf
texi2pdf --batch --clean org.texi
sed: 2: "s/\(^\|.* \)@documenten ...": whitespace after branch
sed: 4: "s/\(^\|.* \)@documenten ...": whitespace after label
sed: 6: "s/\(^\|.* \)@documenten ...": undefined label 'found                                                '
This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013)
 restricted \write18 enabled.
entering extended mode

(/Users/al22/local/emacs/org-mode/doc/org.texi
(/Users/al22/local/emacs/org-mode/doc/texinfo.tex
Loading texinfo [version 2013-09-11.11]: pdf, fonts, markup, glyphs,
page headings, tables, conditionals, indexing, sectioning, toc, environments,
defuns, macros, cross references, insertions,
(/usr/local/texlive/2013/texmf-dist/tex/generic/epsf/epsf.tex
This is `epsf.tex' v2.7.4 <14 February 2011>
) localization, formatting, and turning on texinfo input format.)
(/Users/al22/local/emacs/org-mode/doc/org-version.inc) [1{/usr/local/texlive/20
13/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] [2] [-1] [-2] Chapter 1
[1] [2] Cross reference values unknown; you must run TeX again.
Underfull \hbox (badness 6961) in paragraph at lines 959--964
[]@textrm The four Org com-mands @texttt org-store-link[]@textrm , @texttt org-
capture[]@textrm , @texttt org-agenda[]@textrm , and
[3]
Overfull \hbox (43.6852pt too wide) in paragraph at lines 1050--1050
 []@texttt (add-to-list 'load-path (expand-file-name "/path/to/org-mode/contrib
/lisp" t))[] 
[4] Chapter 2 [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17]
Chapter 3 [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]
[31] [32] [33]
Overfull \hbox (26.43913pt too wide) in paragraph at lines 3189--3189
 []@texttt #+TBLFM: $6=vsum($P1..$P3)::$7=10*$Tot/$max;%.1f::$at=vmean(@-II..@-
I);%.1f[] 
[34] [35]
Overfull \hbox (43.6852pt too wide) in paragraph at lines 3279--3279
 []@texttt #+PLOT: title:"Citas" ind:1 deps:(3) type:2d with:histograms set:"yr
ange [0:]"[] 
[36] Chapter 4 [37] [38] [39] [40] [41] [42] [43]
Overfull \hbox (39.43239pt too wide) in paragraph at lines 3866--3866
 []    @smalltt ("ads"       . "http://adsabs.harvard.edu/cgi-bin/nph-abs_conne
ct?author=%s&db_key=AST")))[] 
[44] Chapter 5 [45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55]
Overfull \hbox (14.94176pt too wide) in paragraph at lines 4733--4733
 []  @texttt "Switch entry to DONE when all subentries are done, to TODO otherw
ise."[] 
[56] [57] Chapter 6 [58] [59] [60] [61] Chapter 7 [62] [63] [64] [65] [66]
[67] [68] [69] [70] Chapter 8 [71]
Overfull \hbox (26.76846pt too wide) in paragraph at lines 5863--5863
 []@texttt * 22:00-23:00 The nerd meeting on every 2nd Thursday of the month[] 

[72] [73] [74] [75] [76] [77] [78] [79] [80] [81] [82]
Overfull \hbox (57.43813pt too wide) in paragraph at lines 6587--6587
 []             [][]$@textsy h$@textrm un-de-fined$@textsy i$ @textrm [Match-in
g tags and prop-er-ties], page $@textsy h$@textrm un-de-fined$@textsy i$[][] @t
extrm for the match syntax.[] 
[83] [84] [85] [86]
/Users/al22/local/emacs/org-mode/doc/org.texi:6840: Argument of \, has an extra
 }.
<inserted text> 
                \par 
<to be read again> 
                   }
\dosubindwrite ...s 0}\xdef \indexsorttmp {\temp }
                                                  }\edef \temp {\write \writ...

\safewhatsit #1->\ifhmode #1
                            \else \whatsitskip = \lastskip \edef \lastskipma...

\dosubind ...dcsname }\safewhatsit \dosubindwrite 
                                                  }\fi 
l.2 @kindex @xeatspaces {C-c C-x @,}
                                    
...
l.6840 ...{C-c C-x \,,org-timer-pause-or-continue}
                                                  
Runaway argument?
/Users/al22/local/emacs/org-mode/doc/org.texi:6840: Paragraph ended before \, w
as complete.
<to be read again> 
                   \par 
<to be read again> 
                   }
\dosubindwrite ...s 0}\xdef \indexsorttmp {\temp }
                                                  }\edef \temp {\write \writ...

\safewhatsit #1->\ifhmode #1
                            \else \whatsitskip = \lastskip \edef \lastskipma...

\dosubind ...dcsname }\safewhatsit \dosubindwrite 
                                                  }\fi 
l.2 @kindex @xeatspaces {C-c C-x @,}
                                    
...
l.6840 ...{C-c C-x \,,org-timer-pause-or-continue}
                                                  
/Users/al22/local/emacs/org-mode/doc/org.texi:6840: Argument of @, has an extra
 }.
<inserted text> 
                @par 
<to be read again> 
                   }
@tclose ...n @rawbackslash @plainfrenchspacing #1}
                                                  @null 
@kbdsub ...@kbdfont @setupmarkupstyle {kbd}@look }
                                                  }@fi 
@kbd ...ook {#1}@expandafter @kbdsub @look ??@par 
                                                  }
@look ->@kbd {@xeatspaces {C-c C-x @,}}
                                        @hskip 0pt plus 1filll @code {@xeats...
...
l.6840 ...{C-c C-x \,,org-timer-pause-or-continue}
                                                  
Runaway argument?
/Users/al22/local/emacs/org-mode/doc/org.texi:6840: Paragraph ended before @, w
as complete.
<to be read again> 
                   @par 
<to be read again> 
                   }
@tclose ...n @rawbackslash @plainfrenchspacing #1}
                                                  @null 
@kbdsub ...@kbdfont @setupmarkupstyle {kbd}@look }
                                                  }@fi 
@kbd ...ook {#1}@expandafter @kbdsub @look ??@par 
                                                  }
@look ->@kbd {@xeatspaces {C-c C-x @,}}
                                        @hskip 0pt plus 1filll @code {@xeats...
...
l.6840 ...{C-c C-x \,,org-timer-pause-or-continue}
                                                  
Chapter 9 [87] [88] [89] [90] [91] [92] [93] [94] [95] [96] [97] Chapter 10
[98] [99] [100] [101]
Overfull \hbox (21.1971pt too wide) in paragraph at lines 7923--7923
[][][]@smalltt org-anniversary[] @smallrm is just like @smalltt diary-anniversa
ry[]@smallrm , but the ar-gu-ment or-der is al-ways ac-cord-ing to ISO and ther
e-
[102] [103] [104] [105] [106] [107] [108] [109] [110] [111] [112] [113]
[114] [115] [116] [117] [118] [119] [120] [121] [122] [123] [124] [125]
[126] Chapter 11 [127] [128] [129] [130]
Overfull \hbox (26.43913pt too wide) in paragraph at lines 9958--9958
 []@texttt In line [[(sc)]] we remember the current position.  [[(jump)][Line (
jump)]][] 
[131] [132] [133] [134] [135] [136] Chapter 12 [137] [138] [139] [140]
Underfull \hbox (badness 8170) in paragraph at lines 10760--10764
 @texttt stat:[][]@textrm Toggle in-clu-sion of statis-tics cook-ies (@texttt o
rg-export-with-statistics-
[141] [142] [143] [144]
Overfull \hbox (29.9825pt too wide) in paragraph at lines 11093--11093
 []@smalltt #+COLUMNS: %45ITEM %10BEAMER_ENV(Env) %10BEAMER_ACT(Act) %4BEAMER_C
OL(Col) %8BEAMER_OPT(Opt)[] 
[145] [146] [147] [148]
Overfull \hbox (111.77094pt too wide) in paragraph at lines 11446--11446
[][][]@smallrm Installation in-struc-tions can be found on the Math-Jax web-sit
e, see [][]@smalltt http://www.mathjax.org/resources/docs/?installation.html[][
][]@smallrm .| 
[149] [150]
Overfull \hbox (101.17207pt too wide) in paragraph at lines 11562--11562
 []@texttt #+HTML_HEAD_EXTRA: <link rel="alternate stylesheet" type="text/css" 
href="style2.css" />[] 
[151] [152] [153] [154] [155]
Overfull \hbox (37.93651pt too wide) in paragraph at lines 11929--11929
 []@texttt #+ATTR_LATEX: :float wrap :width 0.38\textwidth :placement {r}{0.4\t
extwidth}[] 
[156] [157] [158] [159]
Overfull \hbox (25.1256pt too wide) in paragraph at lines 12250--12250
 []@texttt #+ODT_STYLES_FILE: ("/path/to/file.ott" ("styles.xml" "image/hdr.png
"))[] 
[160] [161] [162] [163]
Overfull \hbox (72.42863pt too wide) in paragraph at lines 12560--12560
 []      @texttt (("__Figure__" "Illustration" "value" "Figure" org-odt--enumer
able-image-p)))[] 
[164] [165] [166] [167]
Overfull \hbox (7.81532pt too wide) in paragraph at lines 12898--12899
 @textrm `@texttt CustomFirstColumnTableCell[]@textrm '[]| 

Overfull \hbox (5.62498pt too wide) in paragraph at lines 12899--12900
 @textrm `@texttt CustomFirstColumnTableParagraph[]@textrm '[]| 

Overfull \hbox (2.06664pt too wide) in paragraph at lines 12901--12902
 @textrm `@texttt CustomLastColumnTableCell[]@textrm '[]| 

Overfull \hbox (2.06664pt too wide) in paragraph at lines 12916--12917
 @textrm `@texttt CustomEvenColumnTableCell[]@textrm '[]| 

Underfull \hbox (badness 10000) in paragraph at lines 12930--12935
@smalltt table:use-first-column-styles[]@smallrm , @smalltt table:use-last-colu
mn-styles[]@smallrm , @smalltt table:use-banding-

Overfull \hbox (38.68277pt too wide) in paragraph at lines 12946--12950
 []@textrm For ex-am-ple, the en-try be-low de-fines two dif-fer-ent ta-ble sty
les `@texttt TableWithHeaderRowAndColumn[]@textrm '[]
[168] [169]
Overfull \hbox (43.6852pt too wide) in paragraph at lines 13103--13103
 []@texttt #+TEXINFO_PRINTED_TITLE: This Long Title@inlinefmt{tex,@*} Is Broken
 in @TeX{}[] 
[170] [171] [172] [173] [174] [175] [176]
Overfull \hbox (14.94176pt too wide) in paragraph at lines 13586--13586
 []@texttt #+BIND: org-export-filter-strike-through-functions (tmp-f-strike-thr
ough)[] 
[177] Chapter 13 [178] [179] [180] [181] [182] [183] [184] [185] [186] [187]
Chapter 14 [188] [189] [190] [191] [192]
Overfull \hbox (37.93651pt too wide) in paragraph at lines 14570--14570
 []@texttt #+CALL: <name>[<inside header arguments>](<arguments>) <end header a
rguments>[] 

Overfull \hbox (72.42863pt too wide) in paragraph at lines 14577--14577
 []@texttt ... call_<name>[<inside header arguments>](<arguments>)[<end header 
arguments>] ...[] 
[193] [194] [195] [196] [197] [198] [199] [200] [201] [202] [203] [204]
[205] [206] [207] [208] [209] [210] [211] [212]
Overfull \hbox (14.94176pt too wide) in paragraph at lines 15971--15971
 []@texttt #+begin_src dot :post attr_wrap(width="5cm", data=*this*) :results d
rawer[] 
[213] [214]
Underfull \hbox (badness 10000) in paragraph at lines 16233--16234
 @texttt org-babel-do-key-sequence-in-edit-
[215]
Overfull \hbox (14.94176pt too wide) in paragraph at lines 16277--16277
 []@texttt (add-to-list 'load-path (expand-file-name \"~/src/org/contrib/lisp/\
" t))[] 
[216] Chapter 15 [217] [218] [219]
Overfull \hbox (21.01978pt too wide) in paragraph at lines 16464--16464
 []@texttt (setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)[] 
[220] [221] [222]
Underfull \hbox (badness 10000) in paragraph at lines 16710--16714
 []@textrm The fol-low-ing op-tions in-flu-ence the ta-ble spread-sheet (vari-a
ble
[223] [224] [225]
Underfull \hbox (badness 10000) in paragraph at lines 16989--16989
 @textbf Speed
[226] [227] [228]
Overfull \hbox (84.25534pt too wide) in paragraph at lines 17191--17191
 []            @texttt (define-key yas/keymap [tab] 'yas/next-field-or-maybe-ex
pand)))[] 
[229]
Overfull \hbox (61.26059pt too wide) in paragraph at lines 17210--17210
 []            @texttt (add-to-list 'org-tab-first-hook 'yas/org-very-safe-expa
nd)[] 
[230] Appendix A [231] [232] [233] [234] [235] [236] [237]
Overfull \hbox (32.18782pt too wide) in paragraph at lines 17748--17748
 []    @texttt '(:tstart "!BTBL!" :tend "!ETBL!" :lstart "!BL!" :lend "!EL!" :s
ep "\t")[] 
[238] [239] [240] [241] [242] [243] [244] [245] Appendix B [246] [247]
Appendix C [248] [249] [250] [251] [252] [253] Appendix D [254]
(/Users/al22/local/emacs/org-mode/doc/doclicense.texi [255] [256] [257]
[258] [259] [260] [261]) (Concept index) [262] (Key index) [263]
(Command and function index) [264] (Variable index) [265] [266] )
(see the transcript file for additional information){/usr/local/texlive/2013/te
xmf-dist/fonts/enc/dvips/cm-super/cm-super-t1.enc}</usr/local/texlive/2013/texm
f-dist/fonts/type1/public/amsfonts/cm/cmb10.pfb></usr/local/texlive/2013/texmf-
dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb></usr/local/texlive/2013/texmf-d
ist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/local/texlive/2013/texmf-dis
t/fonts/type1/public/amsfonts/cm/cmr12.pfb></usr/local/texlive/2013/texmf-dist/
fonts/type1/public/amsfonts/cm/cmr7.pfb></usr/local/texlive/2013/texmf-dist/fon
ts/type1/public/amsfonts/cm/cmr8.pfb></usr/local/texlive/2013/texmf-dist/fonts/
type1/public/amsfonts/cm/cmr9.pfb></usr/local/texlive/2013/texmf-dist/fonts/typ
e1/public/amsfonts/cm/cmsl10.pfb></usr/local/texlive/2013/texmf-dist/fonts/type
1/public/amsfonts/cm/cmsl9.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/
public/amsfonts/cm/cmsltt10.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1
/public/amsfonts/cm/cmsy10.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/
public/amsfonts/cm/cmsy9.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/pu
blic/amsfonts/cm/cmti10.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/pub
lic/amsfonts/cm/cmti9.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/publi
c/amsfonts/cm/cmtt10.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/public
/amsfonts/cm/cmtt12.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/public/
amsfonts/cm/cmtt8.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/public/am
sfonts/cm/cmtt9.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/public/cm-s
uper/sfrm0900.pfb></usr/local/texlive/2013/texmf-dist/fonts/type1/public/cm-sup
er/sfrm1095.pfb>
Output written on org.pdf (270 pages, 1020702 bytes).
Transcript written on org.log.
/usr/bin/texi2dvi: pdftex exited with bad status, quitting.
/usr/bin/texi2dvi: see org.log for errors.
make[1]: *** [org.pdf] Error 1
make: *** [pdf] Error 2
--8<---------------cut here---------------end--------------->8---

^ permalink raw reply	[relevance 4%]

* Bug: [Capture] wrongly duplicated date tree outlines [8.2.10]
@ 2014-11-20 20:37  3% kuanyui
  0 siblings, 0 replies; 200+ results
From: kuanyui @ 2014-11-20 20:37 UTC (permalink / raw)
  To: emacs-orgmode


I want to have a `file+datetree` for Org-mode's Capture, so I set like this:

    (setq org-capture-templates
          '(("D" "Diary + Timer" entry
             (file+datetree (concat org-directory "/diary/diary.org"))
             "* %^{Description: } %^g  \n  %i %?\n" :clock-in t :clock-keep t)
    	    ("d" "Diary" entry
             (file+datetree (concat org-directory "/diary/diary.org"))
             "* %? %U")
            ))

And use these captures to add items for `diary.org` several times. I expect the file has:

    * 2014   
    ** 2014-11 11 月
    *** 2014-11-21 金曜日
    **** test1 [2014-11-21 金 03:08]
    **** test2 [2014-11-21 金 03:08]
    **** test3 [2014-11-21 金 03:08]

But what I get is like this:

    * 2014
    ** 2014-11 11 月
    *** 2014-11-21 金曜日
    **** test1 [2014-11-21 金 03:08]
    ** 2014-11 11 月
    *** 2014-11-21 金曜日
    **** test2 [2014-11-21 金 03:09]
    ** 2014-11 11 月
    *** 2014-11-21 金曜日
    **** test3 [2014-11-21 金 03:09]

How to solve this problem...? (I've ever used Org's Capture one year
ago, and at that time it worked just liked I wish; I have no idea why it
becomes this.)

I just asked this problem on StackExchange:
http://emacs.stackexchange.com/questions/3757/orgs-capture-annoying-duplicated-date-tree-outlines
And it seems a bug of Org-mode itself.

Emacs  : GNU Emacs 24.4.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.10.9)
 of 2014-10-23 on kuanyui-laptop.site
Package: Org-mode version 8.2.10 (release_8.2.10 @ /usr/local/share/emacs/24.4/lisp/org/)

current state:
==============
(setq
 org-tab-first-hook '(org-hide-block-toggle-maybe org-src-native-tab-command-maybe
		      org-babel-hide-result-toggle-maybe org-babel-header-arg-expand)
 outline-minor-mode-hook '(wikipedia-outline-magic-keys)
 org-latex-classes '(("article"
		      "\n\\documentclass[12pt,a4paper]{article}\n\\usepackage[margin=2cm]{geometry}\n\\usepackage{fontspec}\n\\setromanfont{cwTeXMing}\n\n\\usepackage{etoolbox}  % Quote部份的字型設定\n\\newfontfamily\\quotefont{cwTeXFangSong}\n\\AtBeginEnvironment{quote}{\\quotefont\\small}\n\n\\setmonofont[Scale=0.9]{Courier} % 等寬字型 [FIXME] Courier 中文會爛掉!\n\\font\\cwSong=''cwTeXFangSong'' at 10pt\n%\\font\\cwHei=''cwTeXHeiBold'' at 10p %不知為何會爆掉\n\\font\\cwYen=''cwTeXYen'' at 10pt\n\\font\\cwKai=''cwTeXKai'' at 10pt\n\\font\\cwMing=''cwTeXMing'' at 10pt\n\\font\\wqyHei=''文泉驛正黑'' at 10pt\n\\font\\wqyHeiMono=''文泉驛等寬正黑'' at 10pt\n\\font\\wqyHeiMicro=''文泉驛微米黑'' at 10pt\n\\XeTeXlinebreaklocale ``zh''\n\\XeTeXlinebreakskip = 0pt plus 1pt\n\\linespread{1.36}\n\n\\usepackage{multicol}\n\n% [FIXME] ox-latex 的設計不良導致hypersetup必須在這裡插入\n\\usepackage{hyperref}\n\\hypersetup{\n  colorlinks=true, %把紅框框移掉改用字體顏色不同來顯示連結\n  linkcolor=[rgb]{0,0.37,0.53},\n  citecolor=[rgb]{0,0.47,0.68},\n  filecolor=[rgb]{0,0.37,0.53},\n  urlcolor=[rgb]{0,0.37,0.53},\n  pagebackref=true,\n  linktoc=all,}\n"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     ("beamer"
		      "\n\\documentclass[presentation]{beamer}\n\\usepackage{fontspec}\n\\setromanfont{wqyHeiMicro}\n\n\\setmonofont[Scale=0.9]{Courier} % 等寬字型 [FIXME] Courier 中文會爛掉!\n\\font\\cwSong=''cwTeXFangSong'' at 10pt\n%\\font\\cwHei=''cwTeXHeiBold'' at 10p %不知為何會爆掉\n\\font\\cwYen=''cwTeXYen'' at 10pt\n\\font\\cwKai=''cwTeXKai'' at 10pt\n\\font\\cwMing=''cwTeXMing'' at 10pt\n\\font\\wqyHei=''文泉驛正黑'' at 10pt\n\\font\\wqyHeiMono=''文泉驛等寬正黑'' at 10pt\n\\font\\wqyHeiMicro=''文泉驛微米黑'' at 10pt\n\\XeTeXlinebreaklocale ``zh''\n\\XeTeXlinebreakskip = 0pt plus 1pt\n\\linespread{1.36}\n\n"
		      ("\\section{%s}" . "\\section*{%s}")
		      ("\\subsection{%s}" . "\\subsection*{%s}")
		      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
		      ("\\paragraph{%s}" . "\\paragraph*{%s}")
		      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
		     )
 org-latex-default-packages-alist '(("" "hyperref" nil) ("AUTO" "inputenc" t)
				    ("" "fixltx2e" nil) ("" "graphicx" t)
				    ("" "longtable" nil) ("" "float" nil) ("" "wrapfig" nil)
				    ("" "rotating" nil) ("normalem" "ulem" t)
				    ("" "amsmath" t) ("" "textcomp" t) ("" "marvosym" t)
				    ("" "wasysym" t) ("" "amssymb" t) "\\tolerance=1000")
 org-speed-command-hook '(org-speed-command-default-hook org-babel-speed-command-hook)
 org-occur-hook '(org-first-headline-recenter)
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-html-format-drawer-function '(lambda (name contents) contents)
 org-log-done 'time
 org-latex-format-inlinetask-function 'ignore
 org-confirm-shell-link-function 'yes-or-no-p
 org-image-actual-width '(300)
 org-ascii-format-inlinetask-function 'org-ascii-format-inlinetask-default
 org-latex-pdf-process '("xelatex -interaction nonstopmode -output-directory %o %f"
			 "xelatex -interaction nonstopmode -output-directory %o %f"
			 "xelatex -interaction nonstopmode -output-directory %o %f")
 org-file-apps '((auto-mode . emacs) ("\\.mm\\'" . default) ("\\.x?html?\\'" . "xdg-open %s")
		 ("\\.pdf\\'" . "kde-open %s") ("\\.jpg\\'" . "kde-open %s"))
 org-agenda-custom-commands '(("w" todo "STARTED")
			      ("D" "Daily Action List"
			       ((agenda ""
				 ((org-agenda-ndays 1)
				  (org-agenda-sorting-strategy
				   (quote ((agenda time-up priority-down tag-up))))
				  (org-deadline-warning-days 0))
				 )
				)
			       )
			      ("P" "Projects" ((tags "Project")))
			      (" " "Agenda"
			       ((todo "STARTED"
				 ((org-agenda-overriding-header
				   "What you should doing right now!")
				  (org-tags-match-list-sublevels nil))
				 )
				(todo "WAITING"
				 ((org-agenda-overriding-header
				   "Things waiting on the perenially disorganised masses")
				  (org-tags-match-list-sublevels nil))
				 )
				(agenda "Timetable, diary & date tasks"
				 ((org-agenda-ndays 7) (org-deadline-warning-days 45)))
				(todo ""
				 ((org-agenda-overriding-header "All other TODOs")
				  (org-agenda-todo-ignore-scheduled t)
				  (org-agenda-todo-ignore-deadlines t)
				  (org-agenda-todo-ignore-with-date t)
				  (org-agenda-todo-ignore-timestamp t)
				  (org-agenda-skip-function
				   (quote (ky/org-agenda-skip-tag "Project")))
				  )
				 )
				(tags-todo "Project"
				 ((org-agenda-overriding-header "Projects' TODOs")))
				)
			       )
			      ("d" "Upcoming deadlines" agenda ""
			       ((org-agenda-entry-types (quote (:deadline)))
				(org-agenda-ndays 1) (org-deadline-warning-days 60)
				(org-agenda-time-grid nil))
			       )
			      ("c" "Weekly schedule" agenda ""
			       ((org-agenda-ndays 7)
				(org-agenda-repeating-timestamp-show-all t)
				(org-agenda-skip-function
				 (quote
				  (org-agenda-skip-entry-if (quote deadline)
				   (quote scheduled))
				  )
				 )
				)
			       )
			      ("P" "Printed agenda"
			       ((agenda ""
				 ((org-agenda-ndays 7) (org-agenda-start-on-weekday nil)
				  (org-agenda-repeating-timestamp-show-all t)
				  (org-agenda-entry-types (quote (:timestamp :sexp))))
				 )
				(agenda ""
				 ((org-agenda-ndays 1) (org-deadline-warning-days 7)
				  (org-agenda-todo-keyword-format "[ ]")
				  (org-agenda-scheduled-leaders (quote ("" "")))
				  (org-agenda-prefix-format "%t%s"))
				 )
				(todo "TODO"
				 ((org-agenda-prefix-format "[ ] %T: ")
				  (org-agenda-sorting-strategy (quote (tag-up priority-down)))
				  (org-agenda-todo-keyword-format "")
				  (org-agenda-overriding-header
				   "\nTasks by Context\n------------------\n")
				  )
				 )
				)
			       ((org-agenda-with-colors nil) (org-agenda-compact-blocks t)
				(org-agenda-remove-tags t) (ps-number-of-columns 2)
				(ps-landscape-mode t))
			       ("~/agenda.ps"))
			      )
 org-agenda-block-separator 45
 org-return-follows-link t
 org-latex-format-headline-function 'org-latex-format-headline-default-function
 org-default-notes-file "~/org/notes.org"
 org-capture-templates '(("t" "Todo" entry
			  (file+headline (concat org-directory "/agenda/Todo.org") "Todo")
			  "** TODO% ? %^G\n  %i")
			 ("s" "School" entry
			  (file+headline (concat org-directory "/agenda/School.org") "School")
			  "** TODO %?\n  %i")
			 ("b" "Buy" entry
			  (file+headline (concat org-directory "/agenda/Todo.org") "Buy")
			  "** TODO %?\n  %i")
			 ("r" "Reading" entry
			  (file+headline (concat org-directory "/agenda/Reading.org")
			   "Reading")
			  "** %? %i :Reading:")
			 ("D" "Diary + Timer" entry
			  (file+datetree (concat org-directory "/diary/diary.org"))
			  "* %^{Description: } %^g  \n  %i %?\n" :clock-in t :clock-keep t)
			 ("d" "Diary" entry
			  (file+datetree (concat org-directory "/diary/diary.org")) "* %? %U")
			 ("e" "Event" entry
			  (file+headline (concat org-directory "/agenda/Event.org") "Event")
			  "** %? %^g\n%^{Event's date&time? }T\n  %i")
			 ("c" "calfw2org" entry (file nil) "** %?\n %(cfw:org-capture-day)"))
 org-after-todo-state-change-hook '(org-clock-out-if-current)
 org-latex-format-drawer-function '(lambda (name contents) contents)
 org-odt-format-headline-function 'ignore
 org-src-mode-hook '(org-src-babel-configure-edit-buffer org-src-mode-configure-edit-buffer)
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-babel-pre-tangle-hook '(save-buffer)
 org-log-redeadline t
 org-agenda-dim-blocked-tasks nil
 org-mode-hook '(org-clock-load (closure (t) nil (setq truncate-lines nil))
		 #[nil "\300\301\302\303\304$\207"
		   [org-add-hook change-major-mode-hook org-show-block-all append local] 5]
		 #[nil "\300\301\302\303\304$\207"
		   [org-add-hook change-major-mode-hook org-babel-show-result-all append
		    local]
		   5]
		 org-babel-result-hide-spec org-babel-hide-all-hashes
		 (lambda nil (pangu-spacing-mode 1)
		  (set (make-local-variable (quote pangu-spacing-real-insert-separtor)) t))
		 (closure (t) nil
		  (define-key org-mode-map (kbd "C-c SPC") (quote ace-jump-word-mode))
		  (define-key org-mode-map (kbd "C-c C-e") (quote org-export-dispatch)))
		 )
 org-ascii-format-drawer-function '(lambda (name contents width) contents)
 org-odt-format-inlinetask-function 'ignore
 org-clock-persist 'history
 org-ctrl-c-ctrl-c-hook '(org-babel-hash-at-point org-babel-execute-safely-maybe)
 org-cycle-hook '(org-cycle-hide-archived-subtrees org-cycle-hide-drawers
		  org-cycle-hide-inline-tasks org-cycle-show-empty-lines
		  org-optimize-window-after-visibility-change)
 org-log-reschedule 'note
 org-todo-keywords '((type "TODO(t!)" "STARTED(s!)" "WAITING(w!)" "APPT(a!)" "|" "DONE(d!)")
		     (type "PROJECT(p!)" "|" "DONE(d!)")
		     (type "|" "CANCELLED(x@)" "DEFERRED(f@)"))
 org-babel-tangle-lang-exts '(("latex" . "tex") ("emacs-lisp" . "el"))
 org-confirm-elisp-link-function 'yes-or-no-p
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-log-into-drawer t
 org-odt-format-drawer-function '(lambda (name contents) contents)
 org-html-head "<style type=\"text/css\">\n* {\n    font-family:WenQuanYi Micro Hei,Microsoft JhengHei,Helvetica,sans-serif;\n    color: #555555;\n    }\n\nbody {\n    text-align: center;\n    background-color: hsl(45,30%,80%);\n    background-image:\n    repeating-linear-gradient(120deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 2px, transparent 1px, transparent 60px),\n    repeating-linear-gradient(60deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 2px, transparent 1px, transparent 60px),\n    linear-gradient(60deg, rgba(0,0,0,.06) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.06) 75%, rgba(0,0,0,.06)),\n    linear-gradient(120deg, rgba(0,0,0,.06) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.06) 75%, rgba(0,0,0,.06));\n    background-size: 70px 120px;\n}\n\n#content {\n    margin: 0px auto;\n    width: 1200px;\n    text-align:left;\n    background-color: rgba(255, 255, 255, 1);\n    border-radius: 7px 7px 0 0;\n    box-shadow: 0 0 0.5em rgba(0,0,0,0.2);\n    padding-bottom: 30px;\n}\n\n#content > p {\n    padding-left: 60px;\n}\n\n\n#postamble {\n    position: relative;\n    z-index: 1;\n    font-size:0.8em;\n    color: #ffffff !important;\n    background-color: #555555 !important;\n    margin: -1.2em auto 0;\n    width: 1180px;\n    background-color: #ffffff;\n    border-radius: 0 0 7px 7px;\n    padding: 30px 10px 10px 10px;\n    box-shadow: 0 0 0.5em rgba(0,0,0,0.2);\n    text-shadow: 0px -1px rgba(0, 0, 0, 0.3);\n\n    background-color: #828282;\n    background-image: radial-gradient(#707070 50%, transparent 51%);\n    background-size: 4px 4px;\n}\n#postamble p {\n    margin: 0;\n    color: #eeeeee !important;\n}\n\n#postamble a {\n    color: #5fafd7;\n}\n\n#table-of-contents {\n    margin: 0 30px;\n    padding: 0 15px 10px 15px;\n    border-top: 4px solid #D4DDE0;\n    border-bottom: 4px solid #D4DDE0;\n    background-color: #E9EEF1;\n    text-shadow: 0 1px 0 hsl(202,100%,100%);\n}\n\n#table-of-contents h2 {\n    color: hsl(202,40%,52%);\n    text-shadow: 0 1px 0 hsl(202,100%,100%);\n    border-left: none;\n    margin-left: 0;\n    padding-left: 0;\n}\n\nimg {\n    max-width:100%;\n    max-height:100%;\n}\na {\n    color: #005f87;\n    text-decoration: none;\n}\n\na:hover {\n    color: #005f87;\n    text-decoration: underline;\n}\n\nh1 {\n    color: #eeeeee;\n    text-shadow: 0px -1px rgba(0, 0, 0, 0.5);\n    font-family: Lato,Lucida Grande,LiHei Pro,WenQuanYi Micro Hei,Arial,sans-serif;\n    font-weight: 400;\n    margin-top: 0px;\n    padding: 20px 0 10px 0;\n    background-color: #828282;\n    background-image: radial-gradient(#707070 50%, transparent 51%);\n    background-size: 4px 4px;\n    border-radius: 7px 7px 0 0;\n}\nh2 {\n    color: #777;\n    border-left: 5px solid #777;\n    margin-left: -30px;\n    padding-left: 25px;\n}\n\n.outline-2 { padding: 0px 30px; }\n.outline-3 { padding: 0px 30px; }\n\n.outline-text-2 { padding: 0px 0px; }\n.outline-text-3 { padding: 0px 0px; }\n.example { }\npre {\n    border: 1pt solid #ddd;\n    background-color: #f2f2f2;\n    box-shadow: 0 0 1em rgba(0,0,0,0.05);\n    border-radius:5px;\n    padding: 5pt;\n    font-family: courier, monospace;\n    font-size: 90%;\n    overflow:auto;\n    margin: 0.5em 2em;\n}\n\npre.src:before {\n    background-color: rgba(0, 0, 0, 0.5);\n    color: #fff;\n    border-radius: 5px;\n    border: none;\n    top: -10px;\n    right: 10px;\n    padding: 3px 7px;\n    position: absolute;\n}\n\ncode {\n    border: 1pt solid #ddd;\n    background-color: #eee;\n    padding: 0 3px;\n    border-radius: 3px;\n    position: relative;\n    margin-top: -3px;\n    font-family: courier, monospace;\n    font-size: 80%;\n}\n\nblockquote {\n    font-style:italic;\n    background: hsl(44,80%,95%);\n    border-left: 5px solid hsl(44,25%,70%);\n    margin: 1.5em 2em;\n    padding: 0.5em 10px 0.5em 4em;\n    quotes: '\\201C''\\201D''\\2018''\\2019';\n}\nblockquote:before {\n    color: #ccc;\n    position: absolute;\n    margin-top: -0.03em;\n    margin-left: -1.3em;\n    color: hsl(44,25%,85%);\n    font-size: 5em;\n    content: '\\201C' !important;\n}\nblockquote p {\n    display: inline;\n    font-family:'Times New Roman', Times, serif !important;\n}\nblockquote p a {\n    font-family:'Times New Roman', Times, serif !important;\n      }\n\n.done {\n    background-color: #d7ff87;\n    color: #008700;\n    border: 1px solid #5faf00;\n    border-radius: 3px;\n    padding:0px 2px;\n    top: -1px;\n    position: relative;\n    font-family:WenQuanYi Micro Hei,Microsoft JhengHei,Helvetica,sans-serif;\n    font-weight: bold;\n    font-size:0.8em;\n}\n.todo {\n    background-color: #ffafaf;\n    color: #a40000;\n    border: 1px solid #dd0000;\n    border-radius: 3px;\n    padding:0px 2px;\n    top: -1px;\n    position: relative;\n    font-family:WenQuanYi Micro Hei,Microsoft JhengHei,Helvetica,sans-serif;\n    font-weight: bold;\n    font-size:0.8em;\n}\n.tag { float:right; color:red; }\n\nh2.footnotes {\n    margin-left: 0;\n}\n#text-footnotes {\n    margin-left: 30px;\n}\n\n</style>"
 org-html-format-headline-function 'ignore
 org-html-format-inlinetask-function 'ignore
 org-agenda-files '("~/org/agenda/Event.org" "~/org/agenda/School.org"
		    "~/org/agenda/Reading.org" "~/org/agenda/Project.org"
		    "~/org/agenda/Learning.org" "~/org/agenda/Todo.org")
 org-clock-out-hook '(org-clock-remove-empty-clock-drawer)
 org-src-fontify-natively t
 )

^ permalink raw reply	[relevance 3%]

* Bug: Cannot export this file as HTML. [8.2.6 (8.2.6-18-gaaae4a-elpa @ /home/kuanyui/.emacs.d/elpa/org-20140512/)]
@ 2014-05-12 13:23  2% kuanyui
  0 siblings, 0 replies; 200+ results
From: kuanyui @ 2014-05-12 13:23 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 304 bytes --]


I encountered a strange question, that this file cannot be exported by
org-mode's HTML exporter, which just return "Wrong type argument:
stringp nil". But I cannot find out where the point is. (And, all the
other files can be outputed without any question.)

I attached this file for reproducing issue.

[-- Attachment #2: The org file. --]
[-- Type: text/plain, Size: 16485 bytes --]

* 第一部份

** What is the IP address and TCP port number used by the client computer (source) that is transferring the file to gaia.cs.umass.edu?
#+BEGIN_QUOTE
 To answer this question, it ’ s probably easiest to select an HTTP message and explore the details of the TCP packet used to carry this HTTP message, using the “ details of the selected packet header window ” (refer to Figure 2 in the “ Getting Started with Wireshark ” Lab if you ’ re uncertain about the Wireshark windows.
#+END_QUOTE
Source: 192.168.0.103:54131
: Source: 192.168.0.103 (192.168.0.103)
: Destination: 128.119.245.12 (128.119.245.12)
: Transmission Control Protocol, Src Port: 54131 (54131), Dst Port: http (80), Seq: 1, Ack: 1, Len: 633
** What is the IP address of gaia.cs.umass.edu? On what port number is it sending and receiving TCP segments for this connection? 
(輸出同上)

Distination: 128.119.245.12:80
** What is the IP address and TCP port number used by your client computer (source) to transfer the file to gaia.cs.umass.edu? 
Source: 192.168.0.103:54131

Destination: 128.119.245.12:80

(這題想問的跟第一題有什麼不同的地方?)
* 第二部份
** What is the sequence number of the TCP SYN segment that is used to initiate the TCP connection between the client computer and gaia.cs.umass.edu? What is it in the segment that identifies the segment as a SYN segment?
TCP SYN 的 SeqNum 為 0;上面寫著[SYN, ACK]。
#+BEGIN_EXAMPLE
12	0.484590000	128.119.245.12	192.168.0.103	TCP	76	http > 54131 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 SACK_PERM=1 TSval=1687806537 TSecr=883895839 WS=128
...
Transmission Control Protocol, Src Port: 54131 (54131), Dst Port: http (80), Seq: 0, Len: 0
    Source port: 54131 (54131)
    Destination port: http (80)
    [Stream index: 0]
    Sequence number: 0    (relative sequence number)
    Header length: 40 bytes
    Flags: 0x002 (SYN)   # SYN 的 Flag 底加
    Window size value: 29200
    [Calculated window size: 29200]
    Checksum: 0x227d [validation disabled]
    Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
#+END_EXAMPLE
** What is the sequence number of the SYNACK segment sent by gaia.cs.umass.edu to the client computer in reply to the SYN?
Seq 為 0;
*** What is the value of the ACKnowledgement field in the SYNACK segment? How did gaia.cs.umass.edu determine that value?
ACK 為 1。SYNACK = 前一個封包的 Seq +1
#+BEGIN_QUOTE
「第 3 個封包開始的 Seq = 前 1 個 received 封包的 ACK(「我已經收到『到 ACK num 為止的長度』的封包惹」)」?
「第 4 個封包開始的 ACK = 前 1 個 received 封包的 Seq + 長度」
#+END_QUOTE

| 序号 | 方向 | seq                    | ack           |          |
|------+------+------------------------+---------------+----------|
|    1 | A->B | 10000(隨機產生?[fn:4]) | 0             | SYN      |
|    2 | A<-B | 20000(隨機產生?)       | 10000+1=10001 | SYN, ACK |
|    3 | A->B | 10001                  | 20000+1=20001 | ACK      |
表格引用自[[http://hi.baidu.com/jialy1987/item/a4fe100f9bdef138f3eafca9][TCP 三次握手连接及 seq 和 ack 号的正确理解]]

| 序号 | 方向 |   seq | ack                                              | size |
|------+------+-------+--------------------------------------------------+------|
|   23 | A->B | 40000 | 70000                                            | 1514 |
|   24 | B->A | 70000 | 40000+1514-54=41460 # 等等要扣掉 54 嗎?![fn:5] |   54 |
|   25 | A->B | 41460 | 70000+54-54=70000                                | 1514 |
|   26 | B->A | 70000 | 41460+1514-54=42920                              |   54 |
表格引用自[[http://hi.baidu.com/jialy1987/item/a4fe100f9bdef138f3eafca9][TCP 三次握手连接及 seq 和 ack 号的正确理解]]
*** What is it in the segment that identifies the segment as a SYNACK segment?
封包中包含 SYN flag,如下:
#+BEGIN_EXAMPLE
Transmission Control Protocol, Src Port: 54131 (54131), Dst Port: http (80), Seq: 0, Len: 0
    Source port: 54131 (54131)
    Destination port: http (80)
    [Stream index: 0]
    Sequence number: 0    (relative sequence number)
    Header length: 40 bytes
    Flags: 0x002 (SYN)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...0 .... = Acknowledgment: Not set
        .... .... 0... = Push: Not set
        .... .... .0.. = Reset: Not set
        .... .... ..1. = Syn: Set
#+END_EXAMPLE
** What is the sequence number of the TCP segment containing the HTTP POST command? 
封包 No. 14,他的 sequence number 是 1。

封包 No. 168 也有包含 "POST" 一詞,sequence number 是 152050。

#+BEGIN_QUOTE
封包 No. 14 的 TCP segment data(633 bytes)內容是:
#+BEGIN_EXAMPLE
POST /wireshark-labs/lab3-1-reply.htm HTTP/1.1
Host: gaia.cs.umass.edu
Connection: keep-alive
Content-Length: 152321
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://gaia.cs.umass.edu
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36 SUSE/34.0.1847.116
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryAKBJRyvCHAhbb6qs
Referer: http://gaia.cs.umass.edu/wireshark-labs/TCP-wireshark-file1.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
#+END_EXAMPLE
#+END_QUOTE

#+BEGIN_QUOTE
我不確定題目問的是哪一個[fn:2], *因為 No. 168 也有包含 "POST" 一詞(sequence number 是 152050)* ,原本以為題目提到的"the TCP segment containing the HTTP POST"就是這個,但:
1. *Wireshark 在顯示 No.168 時,螢幕最下方多了一個* =Reassembled TCP= *的分頁* 。
2. 而且封包 No. 168 在 Wireshark 裡雖然可以看到整個上傳的 txt 檔完整內容,然而 No.168 這個 *封包本身的的 length 似乎卻只有 973* 。
3. 接在 No. 168 後面出現的封包只剩下一堆 ACK 和最後一個 HTTP 200,而沒有任何實際在「上傳 txt 檔案」的封包。
所以 No. 168 只是 *整個 POST 都結束了才出現的最後一個封包* 、用來告訴對方「我剛剛傳的『第#14, #15,#16.......個封包』是要接在一起的」這樣嗎?
我不太確定自己有沒有搞錯,以下為 wireshark 中,No. 168 的 TCP 欄位顯示的東西:
#+BEGIN_EXAMPLE
168	1.452460000	192.168.0.103	128.119.245.12	HTTP	973	POST /wireshark-labs/lab3-1-reply.htm HTTP/1.1  (text/plain)
      Transmission Control Protocol, Src Port: 54131 (54131), Dst Port: http (80), Seq: 152050, Ack: 1, Len: 905
110 Reassembled TCP Segments (152954 bytes): #14(633), #15(1402), #16(1402), #17(1402), #19(1402), #20(1402), #22(1402), #23(1402), #25(1402), #26(1402), #28(1402), #29(1402), #30(1402), #31(1402), #32(1402), #34(1402), #36(1402), #37(1402)......
......
Segment count: 110
Reassembled TCP length: 152954
Reassembled TCP Data: 504f5354202f77697265736861726b2d6c6162732f6c6162...
#+END_EXAMPLE
然後下面是 No. 168 整個封包在 wireshark 裡看到的東西:
#+BEGIN_EXAMPLE
No.     Time           Source                Destination           Protocol Length Info
    168 1.452460000    192.168.0.103         128.119.245.12        HTTP     973    POST /wireshark-labs/lab3-1-reply.htm HTTP/1.1  (text/plain)
....
Transmission Control Protocol, Src Port: 54131 (54131), Dst Port: http (80), Seq: 152050, Ack: 1, Len: 905
    Source port: 54131 (54131)
    Destination port: http (80)
    [Stream index: 0]
    Sequence number: 152050    (relative sequence number)   #sequence number 在這
    [Next sequence number: 152955    (relative sequence number)]
    Acknowledgment number: 1    (relative ack number)
    Header length: 32 bytes
....
Hypertext Transfer Protocol
    POST /wireshark-labs/lab3-1-reply.htm HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): POST /wireshark-labs/lab3-1-reply.htm HTTP/1.1\r\n]
            [Message: POST /wireshark-labs/lab3-1-reply.htm HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: POST
        Request URI: /wireshark-labs/lab3-1-reply.htm
        Request Version: HTTP/1.1
    Host: gaia.cs.umass.edu\r\n
    Connection: keep-alive\r\n
    Content-Length: 152321\r\n
        [Content length: 152321]
    Cache-Control: max-age=0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n
    Origin: http://gaia.cs.umass.edu\r\n
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36 SUSE/34.0.1847.116\r\n
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryAKBJRyvCHAhbb6qs\r\n
    Referer: http://gaia.cs.umass.edu/wireshark-labs/TCP-wireshark-file1.html\r\n
    Accept-Encoding: gzip,deflate,sdch\r\n
    Accept-Language: en-US,en;q=0.8\r\n
    \r\n
    [Full request URI: http://gaia.cs.umass.edu/wireshark-labs/lab3-1-reply.htm]
    [HTTP request 1/1]
    [Response in frame: 203]
MIME Multipart Media Encapsulation, Type: multipart/form-data, Boundary: "----WebKitFormBoundaryAKBJRyvCHAhbb6qs"
    [Type: multipart/form-data]
    First boundary: ------WebKitFormBoundaryAKBJRyvCHAhbb6qs\r\n
    Encapsulated multipart part:  (text/plain)
        Content-Disposition: form-data; name="file"; filename="alice.txt"\r\n
        Content-Type: text/plain\r\n\r\n
        Line-based text data: text/plain
                            ALICE'S ADVENTURES IN WONDERLAND\r\n
            \r\n
                                      Lewis Carroll\r\n
            \r\n
                           THE MILLENNIUM FULCRUM EDITION 3.0\r\n
            \r\n
...
(以下為上傳的 txt 內容)
#+END_EXAMPLE


#+END_QUOTE
** Consider the TCP segment containing the HTTP POST as the first segment in the TCP connection. What are the sequence numbers of the first six segments in the TCP connection (including the segment containing the HTTP POST)?
*** At what time was each segment sent? When was the ACK for each segment received?
| 編號 |          送出時間 | 收到 ACK 時間 |      RTT | length |
|------+-------------------+---------------+----------+--------|
|   14 |       0.484984000 |   0.716423000 | 0.231439 |    701 |
|   15 |       0.485395000 |   0.716500000 | 0.231105 |   1470 |
|   16 |       0.485438000 |   0.719277000 | 0.233839 |   1470 |
|   17 |       0.485471000 |   0.719443000 | 0.233972 |   1470 |
|   18 | (此為 #14 的 ACK) |               |          |     68 |
|   19 |       0.716467000 |   0.953501000 | 0.237034 |   1470 |
|   20 |       0.716500000 |   0.953607000 | 0.237107 |   1470 |
#+TBLFM: $4=$3-$2

#+BEGIN_EXAMPLE
14	0.484984000	192.168.0.103   128.119.245.12  TCP	701	[TCP segment of a reassembled PDU]
15	0.485395000	192.168.0.103   128.119.245.12  TCP	1470	[TCP segment of a reassembled PDU]
16	0.485438000	192.168.0.103   128.119.245.12  TCP	1470	[TCP segment of a reassembled PDU]
17	0.485471000	192.168.0.103   128.119.245.12  TCP	1470	[TCP segment of a reassembled PDU]
18	0.716423000	128.119.245.12  192.168.0.103   TCP	68		http > 54131 [ACK] Seq=1 Ack=634 Win=7168 Len=0 TSval=1687806769 TSecr=883896072   #14 的 ACK
19	0.716467000	192.168.0.103   128.119.245.12  TCP	1470	[TCP segment of a reassembled PDU]
20	0.716500000	192.168.0.103   128.119.245.12  TCP	1470	[TCP segment of a reassembled PDU]
   # 至此行的 #14~17 與 #19, #20 為題目要的前 6 個 TCP connection segments
21	0.719164000	128.119.245.12  192.168.0.103   TCP	68		http > 54131 [ACK] Seq=1 Ack=2036 Win=9984 Len=0 TSval=1687806770 TSecr=883896073   #15 的 ACK
22	0.719215000	192.168.0.103   128.119.245.12  TCP	1470	[TCP segment of a reassembled PDU]
23	0.719252000	192.168.0.103   128.119.245.12  TCP	1470	[TCP segment of a reassembled PDU]
24	0.719277000	128.119.245.12  192.168.0.103   TCP	68		http > 54131 [ACK] Seq=1 Ack=3438 Win=12928 Len=0 TSval=1687806770 TSecr=883896073   #16 的 ACK
25	0.719299000	192.168.0.103	128.119.245.12	TCP	1470	[TCP segment of a reassembled PDU]
26	0.719391000	192.168.0.103	128.119.245.12	TCP	1470	[TCP segment of a reassembled PDU]
27	0.719443000	128.119.245.12	192.168.0.103	TCP	68	http > 54131 [ACK] Seq=1 Ack=4840 Win=15872 Len=0 TSval=1687806772 TSecr=883896073  #17 的 ACK
28	0.719507000	192.168.0.103	128.119.245.12	TCP	1470	[TCP segment of a reassembled PDU]
29	0.719627000	192.168.0.103	128.119.245.12	TCP	1470	[TCP segment of a reassembled PDU]
30	0.719749000	192.168.0.103	128.119.245.12	TCP	1470	[TCP segment of a reassembled PDU]
31	0.719874000	192.168.0.103	128.119.245.12	TCP	1470	[TCP segment of a reassembled PDU]
32	0.719981000	192.168.0.103	128.119.245.12	TCP	1470	[TCP segment of a reassembled PDU]
33	0.953501000	128.119.245.12	192.168.0.103	TCP	68	http > 54131 [ACK] Seq=1 Ack=6242 Win=18688 Len=0 TSval=1687807006 TSecr=883896304  #19 的 ACK
34	0.953585000	192.168.0.103	128.119.245.12	TCP	1470	[TCP segment of a reassembled PDU]
35	0.953607000	128.119.245.12	192.168.0.103	TCP	68	http > 54131 [ACK] Seq=1 Ack=7644 Win=21632 Len=0 TSval=1687807006 TSecr=883896304  #20 的 ACK
#+END_EXAMPLE

*** Given the difference between when each TCP segment was sent, and when its acknowledgement was received.
看不懂這問題是什麼意思。不就送出的時間順序不一樣嗎?
從上面可以看出 ACK 送來的時間非常不固定。不過我沒有去一個個看 ACK 有沒有也跟送出的時間順序一樣都完美的按照順序送回來。
*** What is the RTT value for each of the six segments? 
見前面的表格。
*** What is the EstimatedRTT value (see page 249 in text) after the receipt of each ACK?
0.23317837261962887
#+BEGIN_SRC elisp
  (let ((ERTT 0.231439))
    (mapcar (lambda (x)
              (setq ERTT (+ (* RTT 0.875) (* x 0.125))))
            '(0.231105 0.233839 0.233972 0.237034 0.237107))
    ERTT)
=> 0.23317837261962887
#+END_SRC

*** What is the length of each of the first six TCP segments?
見前面表格。
*** What is the minimum amount of available buffer space advertised at the received for the entire trace?  Does the lack of receiver buffer space ever throttle the sender?
1. 第一個問題救命啊不知道該從哪裡看。[fn:1]
2. 第二個問題是:沒有,因為資料傳輸過程中封包長度一直都是 1470 沒有因為 buffer 被塞爆而縮小過。[fn:3]
*** Are there any retransmitted segments in the trace file? What did you check for (in the trace) in order to answer this question?
沒有,因為 wireshark 吐出來的整串封包清單都沒有重複的 ACK num。
*** How much data does the receiver typically acknowledge in an ACK? Can you identify cases where the receiver is ACKing every other received segment (see Table 3.2 on page 257 in the text).
1. 1460。
2. 我看不懂這題指的"*every other* received segment"到底在說什麼。[fn:6]
*** What is the throughput (bytes transferred per unit time) for the TCP connection? Explain how you calculated this value.
97842.160 bytes/sec;直接看 Wireshark: Statictics => Summary => Avg. bytes/sec(算作弊嗎?)

整個 dump 出來的檔案大小 175184 bytes;從 SYN 開始直到收到最後一個 ACK 共歷時 1.716571 秒
175184 / 1.716571 = 102054.619355 #呃...我不太確定該怎麼算,不過跟上面的值好像蠻接近的。

* 第三部份
** Use the Time-Sequence-Graph(Stevens) plotting tool to view the sequence number versus time plot of segments being sent from the client to the gaia.cs.umass.edu server. Can you identify where TCP's slowstart phase begins and ends, and where congestion avoidance takes over? Comment on ways in which the measured data differs from the idealized behavior of TCP that we've studied in the text.

** Answer each of two questions above for the trace that you have gathered when you transferred a file from your computer to gaia.cs.umass.edu
* Footnotes

[fn:1] 

[fn:2] 

[fn:3] 到底 buffer 是限制封包長度還是數量啊

[fn:4] 隨機的?

[fn:5] 需要扣掉嗎?!

[fn:6] 


[-- Attachment #3: Type: text/plain, Size: 16830 bytes --]


kuanyui 20140512 GMT+8 

Emacs  : GNU Emacs 24.3.90.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.10.4)
 of 2014-04-13 on kuanyui-laptop.site
Package: Org-mode version 8.2.6 (8.2.6-18-gaaae4a-elpa @ /home/kuanyui/.emacs.d/elpa/org-20140512/)

current state:
==============
(setq
 org-tab-first-hook '(org-hide-block-toggle-maybe org-src-native-tab-command-maybe org-babel-hide-result-toggle-maybe org-babel-header-arg-expand)
 outline-minor-mode-hook '(wikipedia-outline-magic-keys)
 org-latex-classes '(("article"
                      "\n\\documentclass[12pt,a4paper]{article}\n\\usepackage[margin=2cm]{geometry}\n\\usepackage{fontspec}\n\\setromanfont{cwTeXMing}\n\n\\usepackage{etoolbox}  % Quote部份的字型設定\n\\newfontfamily\\quotefont{cwTeXFangSong}\n\\AtBeginEnvironment{quote}{\\quotefont\\small}\n\n\\setmonofont[Scale=0.9]{Courier} % 等寬字型 [FIXME] Courier 中文會爛掉!\n\\font\\cwSong=''cwTeXFangSong'' at 10pt\n%\\font\\cwHei=''cwTeXHeiBold'' at 10p %不知為何會爆掉\n\\font\\cwYen=''cwTeXYen'' at 10pt\n\\font\\cwKai=''cwTeXKai'' at 10pt\n\\font\\cwMing=''cwTeXMing'' at 10pt\n\\font\\wqyHei=''文泉驛正黑'' at 10pt\n\\font\\wqyHeiMono=''文泉驛等寬正黑'' at 10pt\n\\font\\wqyHeiMicro=''文泉驛微米黑'' at 10pt\n\\XeTeXlinebreaklocale ``zh''\n\\XeTeXlinebreakskip = 0pt plus 1pt\n\\linespread{1.36}\n\n\\usepackage{multicol}\n\n% [FIXME] ox-latex 的設計不良導致hypersetup必須在這裡插入\n\\usepackage{hyperref}\n\\hypersetup{\n  colorlinks=true, %把紅框框移掉改用字體顏色不同來顯示連結\n  linkcolor=[rgb]{0,0.37,0.53},\n  citecolor=[rgb]{0,0.47,0.68},\n  filecolor=[rgb]{0,0.37,0.53},\n  urlcolor=[rgb]{0,0.37,0.53},\n  pagebackref=true,\n  linktoc=all,}\n"
                      ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}")
                      ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
                     ("beamer"
                      "\n\\documentclass[presentation]{beamer}\n\\usepackage{fontspec}\n\\setromanfont{wqyHeiMicro}\n\n\\setmonofont[Scale=0.9]{Courier} % 等寬字型 [FIXME] Courier 中文會爛掉!\n\\font\\cwSong=''cwTeXFangSong'' at 10pt\n%\\font\\cwHei=''cwTeXHeiBold'' at 10p %不知為何會爆掉\n\\font\\cwYen=''cwTeXYen'' at 10pt\n\\font\\cwKai=''cwTeXKai'' at 10pt\n\\font\\cwMing=''cwTeXMing'' at 10pt\n\\font\\wqyHei=''文泉驛正黑'' at 10pt\n\\font\\wqyHeiMono=''文泉驛等寬正黑'' at 10pt\n\\font\\wqyHeiMicro=''文泉驛微米黑'' at 10pt\n\\XeTeXlinebreaklocale ``zh''\n\\XeTeXlinebreakskip = 0pt plus 1pt\n\\linespread{1.36}\n\n"
                      ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}")
                      ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}")
                      ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
                     )
 org-latex-default-packages-alist '(("" "hyperref" nil) ("AUTO" "inputenc" t) ("" "fixltx2e" nil) ("" "graphicx" t) ("" "longtable" nil)
                                    ("" "float" nil) ("" "wrapfig" nil) ("" "rotating" nil) ("normalem" "ulem" t) ("" "amsmath" t)
                                    ("" "textcomp" t) ("" "marvosym" t) ("" "wasysym" t) ("" "amssymb" t) "\\tolerance=1000")
 org-speed-command-hook '(org-speed-command-default-hook org-babel-speed-command-hook)
 org-occur-hook '(org-first-headline-recenter)
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-html-format-drawer-function '(lambda (name contents) contents)
 org-log-done 'time
 org-latex-format-inlinetask-function 'ignore
 org-confirm-shell-link-function 'yes-or-no-p
 org-image-actual-width '(300)
 org-ascii-format-inlinetask-function 'org-ascii-format-inlinetask-default
 org-latex-pdf-process '("xelatex -interaction nonstopmode -output-directory %o %f" "xelatex -interaction nonstopmode -output-directory %o %f"
                         "xelatex -interaction nonstopmode -output-directory %o %f")
 org-file-apps '((auto-mode . emacs) ("\\.mm\\'" . default) ("\\.x?html?\\'" . "xdg-open %s") ("\\.pdf\\'" . "kde-open %s")
                 ("\\.jpg\\'" . "kde-open %s"))
 org-agenda-custom-commands '(("w" todo "STARTED")
                              ("D" "Daily Action List"
                               ((agenda ""
                                 ((org-agenda-ndays 1) (org-agenda-sorting-strategy (quote ((agenda time-up priority-down tag-up))))
                                  (org-deadline-warning-days 0))
                                 )
                                )
                               )
                              ("P" "Projects" ((tags "Project")))
                              (" " "Agenda"
                               ((todo "STARTED"
                                 ((org-agenda-overriding-header "What you should doing right now!") (org-tags-match-list-sublevels nil)))
                                (todo "WAITING"
                                 ((org-agenda-overriding-header "Things waiting on the perenially disorganised masses")
                                  (org-tags-match-list-sublevels nil))
                                 )
                                (agenda "Timetable, diary & date tasks" ((org-agenda-ndays 7) (org-deadline-warning-days 45)))
                                (todo ""
                                 ((org-agenda-overriding-header "All other TODOs") (org-agenda-todo-ignore-scheduled t)
                                  (org-agenda-todo-ignore-deadlines t) (org-agenda-todo-ignore-with-date t) (org-agenda-todo-ignore-timestamp t)
                                  (org-agenda-skip-function (quote (ky/org-agenda-skip-tag "Project"))))
                                 )
                                (tags-todo "Project" ((org-agenda-overriding-header "Projects' TODOs"))))
                               )
                              ("d" "Upcoming deadlines" agenda ""
                               ((org-agenda-entry-types (quote (:deadline))) (org-agenda-ndays 1) (org-deadline-warning-days 60)
                                (org-agenda-time-grid nil))
                               )
                              ("c" "Weekly schedule" agenda ""
                               ((org-agenda-ndays 7) (org-agenda-repeating-timestamp-show-all t)
                                (org-agenda-skip-function (quote (org-agenda-skip-entry-if (quote deadline) (quote scheduled)))))
                               )
                              ("P" "Printed agenda"
                               ((agenda ""
                                 ((org-agenda-ndays 7) (org-agenda-start-on-weekday nil) (org-agenda-repeating-timestamp-show-all t)
                                  (org-agenda-entry-types (quote (:timestamp :sexp))))
                                 )
                                (agenda ""
                                 ((org-agenda-ndays 1) (org-deadline-warning-days 7) (org-agenda-todo-keyword-format "[ ]")
                                  (org-agenda-scheduled-leaders (quote ("" ""))) (org-agenda-prefix-format "%t%s"))
                                 )
                                (todo "TODO"
                                 ((org-agenda-prefix-format "[ ] %T: ") (org-agenda-sorting-strategy (quote (tag-up priority-down)))
                                  (org-agenda-todo-keyword-format "") (org-agenda-overriding-header "\nTasks by Context\n------------------\n"))
                                 )
                                )
                               ((org-agenda-with-colors nil) (org-agenda-compact-blocks t) (org-agenda-remove-tags t) (ps-number-of-columns 2)
                                (ps-landscape-mode t))
                               ("~/agenda.ps"))
                              )
 org-agenda-block-separator 45
 org-return-follows-link t
 org-latex-format-headline-function 'org-latex-format-headline-default-function
 org-default-notes-file "~/org/notes.org"
 org-capture-templates '(("t" "Todo" entry (file+headline (concat org-directory "/agenda/Todo.org") "Todo") "** TODO %? %^G\n  %i")
                         ("s" "School" entry (file+headline (concat org-directory "/agenda/School.org") "School") "** TODO %?\n  %i")
                         ("b" "Buy" entry (file+headline (concat org-directory "/agenda/Todo.org") "Buy") "** TODO %?\n  %i")
                         ("r" "Reading" entry (file+headline (concat org-directory "/agenda/Reading.org") "Reading") "** %? %i :Reading:")
                         ("d" "Diary" entry (file+datetree (concat org-directory "/diary/diary.org")) "* %^{Description: } %^g  \n  %i %?\n"
                          :clock-in t :clock-keep t)
                         ("e" "Event" entry (file+headline (concat org-directory "/agenda/Event.org") "Event")
                          "** %? %^g\n%^{Event's date&time? }T\n  %i")
                         ("c" "calfw2org" entry (file nil) "** %?\n %(cfw:org-capture-day)"))
 org-after-todo-state-change-hook '(org-clock-out-if-current)
 org-latex-format-drawer-function '(lambda (name contents) contents)
 org-odt-format-headline-function 'ignore
 org-src-mode-hook '(org-src-babel-configure-edit-buffer org-src-mode-configure-edit-buffer)
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-babel-pre-tangle-hook '(save-buffer)
 org-log-redeadline t
 org-agenda-dim-blocked-tasks nil
 org-mode-hook '((lambda nil (pangu-spacing-mode 1) (set (make-local-variable (quote pangu-spacing-real-insert-separtor)) t))
                 (lambda nil (define-key org-mode-map (kbd "C-c SPC") (quote ace-jump-word-mode))
                  (define-key org-mode-map (kbd "C-c C-e") (quote org-export-dispatch)))
                 org-clock-load (lambda nil (setq truncate-lines nil))
                 #[nil "\300\301\302\303\304$\207" [org-add-hook change-major-mode-hook org-show-block-all append local] 5]
                 #[nil "\300\301\302\303\304$\207" [org-add-hook change-major-mode-hook org-babel-show-result-all append local] 5]
                 org-babel-result-hide-spec org-babel-hide-all-hashes)
 org-refile-targets '(("Todo.org" :maxlevel . 1) ("School.org" :maxlevel . 1) ("Learning.org" :maxlevel . 1) ("Project.org" :maxlevel . 2)
                      ("Event.org" :maxlevel . 1) ("Reading.org" :maxlevel . 1))
 org-ascii-format-drawer-function '(lambda (name contents width) contents)
 org-odt-format-inlinetask-function 'ignore
 org-clock-persist 'history
 org-ctrl-c-ctrl-c-hook '(org-babel-hash-at-point org-babel-execute-safely-maybe)
 org-cycle-hook '(org-cycle-hide-archived-subtrees org-cycle-hide-drawers org-cycle-hide-inline-tasks org-cycle-show-empty-lines
                  org-optimize-window-after-visibility-change)
 org-log-reschedule 'note
 org-todo-keywords '((type "TODO(t!)" "STARTED(s!)" "WAITING(w!)" "APPT(a!)" "|" "DONE(d!)") (type "PROJECT(p!)" "|" "DONE(d!)")
                     (type "|" "CANCELLED(x@)" "DEFERRED(f@)"))
 org-babel-tangle-lang-exts '(("latex" . "tex") ("emacs-lisp" . "el"))
 org-confirm-elisp-link-function 'yes-or-no-p
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-log-into-drawer t
 org-odt-format-drawer-function '(lambda (name contents) contents)
 org-html-head "<style type=\"text/css\">\n* {\n    font-family:WenQuanYi Micro Hei,Microsoft JhengHei,Helvetica,sans-serif;\n    color: #555555;\n    }\n\nbody {\n    text-align: center;\n    background-color: hsl(45,30%,80%);\n    background-image:\n    repeating-linear-gradient(120deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 2px, transparent 1px, transparent 60px),\n    repeating-linear-gradient(60deg, rgba(255,255,255,.1), rgba(255,255,255,.1) 2px, transparent 1px, transparent 60px),\n    linear-gradient(60deg, rgba(0,0,0,.06) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.06) 75%, rgba(0,0,0,.06)),\n    linear-gradient(120deg, rgba(0,0,0,.06) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.06) 75%, rgba(0,0,0,.06));\n    background-size: 70px 120px;\n}\n\n#content {\n    margin: 0px auto;\n    width: 1200px;\n    text-align:left;\n    background-color: rgba(255, 255, 255, 1);\n    border-radius: 7px 7px 0 0;\n    box-shadow: 0 0 0.5em rgba(0,0,0,0.2);\n    padding-bottom: 30px;\n}\n\n#postamble {\n    position: relative;\n    z-index: 1;\n    font-size:0.8em;\n    color: #ffffff !important;\n    background-color: #555555 !important;\n    margin: -1.2em auto 0;\n    width: 1180px;\n    background-color: #ffffff;\n    border-radius: 0 0 7px 7px;\n    padding: 30px 10px 10px 10px;\n    box-shadow: 0 0 0.5em rgba(0,0,0,0.2);\n    text-shadow: 0px -1px rgba(0, 0, 0, 0.3);\n\n    background-color: #828282;\n    background-image: radial-gradient(#707070 50%, transparent 51%);\n    background-size: 4px 4px;\n}\n#postamble p {\n    margin: 0;\n    color: #eeeeee !important;\n}\n\n#postamble a {\n    color: #5fafd7;\n}\n\n#table-of-contents {\n    margin: 0 30px;\n    padding: 0 15px 10px 15px;\n    border-top: 4px solid #D4DDE0;\n    border-bottom: 4px solid #D4DDE0;\n    background-color: #E9EEF1;\n    text-shadow: 0 1px 0 hsl(202,100%,100%);\n}\n\n#table-of-contents h2 {\n    color: hsl(202,40%,52%);\n    text-shadow: 0 1px 0 hsl(202,100%,100%);\n    border-left: none;\n    margin-left: 0;\n    padding-left: 0;\n}\n\nimg {\n    max-width:100%;\n    max-height:100%;\n}\na {\n    color: #005f87;\n    text-decoration: none;\n}\n\na:hover {\n    color: #005f87;\n    text-decoration: underline;\n}\n\nh1 {\n    color: #eeeeee;\n    text-shadow: 0px -1px rgba(0, 0, 0, 0.5);\n    font-family: Lato,Lucida Grande,LiHei Pro,WenQuanYi Micro Hei,Arial,sans-serif;\n    font-weight: 400;\n    margin-top: 0px;\n    padding: 20px 0 10px 0;\n    background-color: #828282;\n    background-image: radial-gradient(#707070 50%, transparent 51%);\n    background-size: 4px 4px;\n    border-radius: 7px 7px 0 0;\n}\nh2 {\n    color: #777;\n    border-left: 5px solid #777;\n    margin-left: -30px;\n    padding-left: 25px;\n}\n\n.outline-2 { padding: 0px 30px; }\n.outline-3 { padding: 0px 30px; }\n\n.outline-text-2 { padding: 0px 0px; }\n.outline-text-3 { padding: 0px 0px; }\n.example { }\npre {\n    border: 1pt solid #ddd;\n    background-color: #f2f2f2;\n    box-shadow: 0 0 1em rgba(0,0,0,0.05);\n    border-radius:5px;\n    padding: 5pt;\n    font-family: courier, monospace;\n    font-size: 90%;\n    overflow:auto;\n    margin: 0.5em 2em;\n}\n\npre.src:before {\n    background-color: rgba(0, 0, 0, 0.5);\n    color: #fff;\n    border-radius: 5px;\n    border: none;\n    top: -10px;\n    right: 10px;\n    padding: 3px 7px;\n    position: absolute;\n}\n\ncode {\n    border: 1pt solid #ddd;\n    background-color: #eee;\n    padding: 0 3px;\n    border-radius: 3px;\n    position: relative;\n    margin-top: -3px;\n    font-family: courier, monospace;\n    font-size: 80%;\n}\n\nblockquote {\n    font-style:italic;\n    background: hsl(44,80%,95%);\n    border-left: 5px solid hsl(44,25%,70%);\n    margin: 1.5em 2em;\n    padding: 0.5em 10px 0.5em 4em;\n    quotes: '\\201C''\\201D''\\2018''\\2019';\n}\nblockquote:before {\n    color: #ccc;\n    position: absolute;\n    margin-top: -0.03em;\n    margin-left: -1.3em;\n    color: hsl(44,25%,85%);\n    font-size: 5em;\n    content: '\\201C' !important;\n}\nblockquote p {\n    display: inline;\n    font-family:'Times New Roman', Times, serif !important;\n}\nblockquote p a {\n    font-family:'Times New Roman', Times, serif !important;\n      }\n\n.done {\n    background-color: #d7ff87;\n    color: #008700;\n    border: 1px solid #5faf00;\n    border-radius: 3px;\n    padding:0px 2px;\n    top: -1px;\n    position: relative;\n    font-family:WenQuanYi Micro Hei,Microsoft JhengHei,Helvetica,sans-serif;\n    font-weight: bold;\n    font-size:0.8em;\n}\n.todo {\n    background-color: #ffafaf;\n    color: #a40000;\n    border: 1px solid #dd0000;\n    border-radius: 3px;\n    padding:0px 2px;\n    top: -1px;\n    position: relative;\n    font-family:WenQuanYi Micro Hei,Microsoft JhengHei,Helvetica,sans-serif;\n    font-weight: bold;\n    font-size:0.8em;\n}\n.tag { float:right; color:red; }\n\n</style>"
 org-html-format-headline-function 'ignore
 org-html-format-inlinetask-function 'ignore
 org-agenda-files '("~/org/agenda/Event.org" "~/org/agenda/School.org" "~/org/agenda/Reading.org" "~/org/agenda/Project.org"
                    "~/org/agenda/Learning.org" "~/org/agenda/Todo.org")
 org-clock-out-hook '(org-clock-remove-empty-clock-drawer)
 org-src-fontify-natively t
 )

^ permalink raw reply	[relevance 2%]

* Re: org-entities: Another issue [was: org-entities: why \lang instead of \langle?]
  @ 2014-03-25 14:02  7%     ` Aaron Ecay
  0 siblings, 0 replies; 200+ results
From: Aaron Ecay @ 2014-03-25 14:02 UTC (permalink / raw)
  To: Anders Johansson, emacs-orgmode

Hi Anders,

2014ko martxoak 25an, Anders Johansson-ek idatzi zuen:
>
> (I continue in the same thread as this is related)
>
> org-entities has:  ("slash" "/" nil "/" "/" "/" "/")
>
> A LaTeX user entering \slash would probably expect to have this exported
> as \slash (which produces a breaking "/", not the same thing as just
> entering "/" in LaTeX).
>
> So it should rather be:  ("slash" "\\slash" nil "/" "/" "/" "/")
>
> Could this be changed without breaking people's documents?

It’s important for LaTeX users to have a way to write “/” into the
output – sometimes it might not possible to use a literal “/” in org,
because of the /emphasis/ markup.

It seems to me (as a user of both latex and html export) that most of
the time I want “/” in the output, regardless of backend.  Maybe (org’s)
\slash should retain its meaning, and there should be a new entity which
obeys your proposal.

It also seems like \slash in latex has some odd properties
wrt. hyphenation:
<https://tex.stackexchange.com/questions/97310/slash-allows-for-hyphenation-of-only-the-word-on-its-left-how-to-fix-it-for-th>.
So maybe latex power users would rather write something more complicated
using the @@latex:\slash\hspace{0pt}@@ syntax.

Thanks,

--
Aaron Ecay

^ permalink raw reply	[relevance 7%]

* Re: Blank page in LaTeX/PDF output
  @ 2014-03-01  1:30  9%         ` Peter Davis
  0 siblings, 0 replies; 200+ results
From: Peter Davis @ 2014-03-01  1:30 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1236 bytes --]

Attached is a simple file that demonstrates this. As is, it does not 
leave a blank page. But if you remove the num:nil option from the second 
line of this file, you do get a blank page.

You (probably) need koma-article class for this. (I didn't install 
anything. It just worked for me.) You don't need the images.

-pd

On 2/28/14, 8:21 PM, Peter Davis wrote:
>
> On 2/28/14, 7:38 PM, Nick Dokos wrote:
>> John is correct, I think, although latex's behavior in leaving an empty
>> page does not make much sense to me. Nevertheless, when I reduce
>> the height of the last image to less than about 7.85 inches, the empty
>> page goes away. AFAICT, num: and toc: settings do not affect this
>> behavior.
>>
>
> Thanks, Nick, but I have confirmed that adding num:nil eliminates the 
> blank page, and removing that re-introduces the blank page. No other 
> changes to the .org file were made. I was wondering if LaTeX has some 
> predisposition to handle numbered section headings differently from 
> unnumbered ones as far as pagination.
>
> I'll try to make a simple, clean sample that reproduces it, but it's 
> going to take some trial-and-error testing.
>
> -pd
>

-- 
----
Peter Davis
The Tech Curmudgeon
www.techcurmudgeon.com


[-- Attachment #2: blank-page-bug.org --]
[-- Type: text/plain, Size: 2738 bytes --]

#+STARTUP: showeverything logdone
#+options: num:nil toc:nil

#+LaTeX_CLASS: koma-article
#+LATEX_HEADER: \setlength{\parskip}{2ex plus 4pt minus 2pt}
#+LATEX_HEADER: \setlength{\parindent}{0pt}
#+LATEX_HEADER: \renewcommand{\baselinestretch}{1.0}
#+LATEX_HEADER: \setlength{\topsep}{-10pt}
#+LATEX_HEADER: \setlength{\partopsep}{0pt}
#+LaTeX_CLASS_OPTIONS: [article,letterpaper,times,12pt,listings-bw,microtype]
#+author: Peter Davis (pdavis)
#+title: My Title

#+ATTR_LATEX: :height 6in
[[/Users/peterdavis/force_a_page_break.png]]

#+ATTR_LATEX: :height 6cm
[[/Users/peterdavis/AS3_2.png]]

/NOTE:/ User actio]ns are indicated in lowercase letters. Software responses are indicated in UPPERCASE LETTERS.

* Lexical Analysis

The following table contains the word "blah" a lot.

#+CAPTION:
#+ATTR_LATEX: :align lp{2.75in}p{2.75in}
|----------------+----------------------------------------------------------+-------------------------------------------------------------------------|
| *blah*         | *blah blah blah*                                         | *blah blah blah blah*                                                   |
|----------------+----------------------------------------------------------+-------------------------------------------------------------------------|
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
|----------------+----------------------------------------------------------+-------------------------------------------------------------------------|

* Storyboard

#+ATTR_LATEX: :height 8.5in
[[/Users/peterdavis/tall_image.png]]


^ permalink raw reply	[relevance 9%]

* Re: Blank page in LaTeX/PDF output
  @ 2014-02-28 17:26  9%   ` Peter Davis
    0 siblings, 1 reply; 200+ results
From: Peter Davis @ 2014-02-28 17:26 UTC (permalink / raw)
  To: John Hendy; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1109 bytes --]


On 2/28/14, 12:03 PM, John Hendy wrote:
> On Fri, Feb 28, 2014 at 10:59 AM, Peter Davis <pfd@pfdstudio.com> wrote:
>> I'm writing a short paper containing tables, images, etc., but I'm getting a
>> blank page in the PDF output. That is, it's completely blank *except* for
>> the page number.
>>
>> Any suggestions on how to trouble-shoot or fix this?
> Probably related to image/table float placement. I've had an image on
> one page trigger a blank page after it, and if your options or the
> size of the image on the next place won't fit on a single page, it
> might be skipping that blank one entirely and moving along to the
> next.
>
> Is it possible to share the document, or could you try to copy that
> .org file, remove the contents of p. 1-4 and 8-9, and then share the
> .org file that generates pages 5, 6 (blank), and 7?

Thanks, John. I figured it has something to do with LaTeX float 
behavior, but I'm trying to understand how to control it through 
org-mode. I'm attaching a small sample that reproduces the problem.

Thanks!
-pd

-- 
Peter Davis
The Tech Curmudgeon
www.techcurmudgeon.com


[-- Attachment #2: blank-page-bug.org --]
[-- Type: text/plain, Size: 2858 bytes --]

#+STARTUP: showeverything logdone
#+options: num:nil
#+OPTIONS:   H:5 num:t \n:nil @:t ::t |:t ^:nil -:t f:t *:t <:t
#+LaTeX_CLASS: koma-article
#+LATEX_HEADER: \setlength{\parskip}{2ex plus 4pt minus 2pt}
#+LATEX_HEADER: \setlength{\parindent}{0pt}
#+LATEX_HEADER: \renewcommand{\baselinestretch}{1.0}
#+LATEX_HEADER: \setlength{\topsep}{-10pt}
#+LATEX_HEADER: \setlength{\partopsep}{0pt}
#+LaTeX_CLASS_OPTIONS: [article,letterpaper,times,12pt,listings-bw,microtype]
#+author: Peter Davis (pdavis)
#+title: My Title

#+ATTR_LATEX: :height 5in
[[/Users/peterdavis/Dropbox/Tufts/COMP171/force_a_page_break.png]]

#+ATTR_LATEX: :height 6cm
[[/Users/peterdavis/Dropbox/Tufts/COMP171/AS3_2.png]]

/NOTE:/ User actions are indicated in lowercase letters. Software responses are indicated in UPPERCASE LETTERS.

* Lexical Analysis

The following table contains the word "blah" a lot.

#+CAPTION:
#+ATTR_LATEX: :align lp{2.75in}p{2.75in}
|----------------+----------------------------------------------------------+-------------------------------------------------------------------------|
| *blah*         | *blah blah blah*                                         | *blah blah blah blah*                                                   |
|----------------+----------------------------------------------------------+-------------------------------------------------------------------------|
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
| blah           | blah blah blah                                           | blah blah blah blah                                                     |
|----------------+----------------------------------------------------------+-------------------------------------------------------------------------|

* Storyboard

#+ATTR_LATEX: :height 8.5in
[[/Users/peterdavis/Dropbox/Tufts/COMP171/Storyboard.png]]


^ permalink raw reply	[relevance 9%]

* Re: fold paragraphs, export only contents of a node, hiding the 'node heading text'
  @ 2013-09-04  0:20  8%                 ` mapcdi
  0 siblings, 0 replies; 200+ results
From: mapcdi @ 2013-09-04  0:20 UTC (permalink / raw)
  To: John Hendy; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 12545 bytes --]




It works for me now!
If now I could only know how to hide just the  DONE  keywords! I know it's:
#+OPTIONS: todo: toggle on/off DONE so the word is not exported, kind of  thing, but couldn't find it.


Here's my .emacs:

(require 'org-latex) ;; It works because my version is < 8.0
(unless (boundp 'org-export-latex-classes)
  (setq org-export-latex-classes nil))
(add-to-list 'org-export-latex-classes
             '("article"
               "\\documentclass{article}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))




And here's my doc.org:
________________________________________________________
#+TITLE:     Hiding the \texttt{paragraph} formatting works fine
#+AUTHOR:
#+DATE:
#+OPTIONS:   H:5 num:t toc:2 \n:nil @:t ::t |:t ^:nil -:t f:t *:t <:t
#+LATEX_HEADER:   \usepackage{titlesec}
#+LATEX_HEADER:   \titleformat{\subsubsection}[runin]{\normalfont\normalsize}{}{}{}[ \mbox{}]
#+LATEX_HEADER:   \titlespacing{\subsubsection}{10pt}{0ex plus 0ex minus 0ex}{0pt}
#+LATEX_HEADER:   \titleformat{\paragraph}[runin]{\normalfont\normalsize}{}{}{}[ \mbox{}]
#+LATEX_HEADER:   \titlespacing{\paragraph}{10pt}{0ex plus 0ex minus 0ex}{0pt}

* Section
** subsection
*** Subsubsection.
Although as demonstrated in this subsubsection, it can work for other headings.
**** It works out fine now for paragraphs.
As intended. I would normally not set the
\texttt{titlesec} 'trick' for headings other than
paragraphs.
**** This trick, I found it here:
http://latex-community.org/forum/viewtopic.php?f=5&t=20169.
So thanks. And also thanks to the great package by none other than Javier
Bezos. Great stuff!

* Section
** subsection
*** Subsubsection. See! Subsubections come out as paragraphs now!
**** My paragraph to start the story.
I would like to start by saying this much.
It was all about being able to \emph{do the folding}.
**** TODO I can even have a paragraph without much text.
**** DONE This next paragraph develops the story a little more.
I would like to continue saying what the story is all
about. Now is not the time to give up the mysterious
\emph{folding}. End of doc.org.
___________________________________________________




I'm posting my solution because I think some more people could find it interesting in this solution.
It could work wonders for structuring your ideas and shuffling them easily as paragraphs in your texts.
Since that's what org-mode is all about here's also my vote for such a feature request.

Thanks to John Hendy.


Best regards,
Mark



El 03/09/2013, a las 21:17, John Hendy <jw.hendy@gmail.com> escribió:

> On Tue, Sep 3, 2013 at 9:48 AM,  <mapcdi@me.com> wrote:
>> So, now that I can hide all the headings I need a way to hide ONLY SOME
>> headings, like those with a todo-like specific text: say UNFINISHEDPAR for
>> unfinished paragraphs and FINISHEDPAR for the ones finished.
>> 
> 
> I haven't used them, but I believe filters might be the way to go for this:
> - http://orgmode.org/worg/dev/org-export-reference.html#filter-system
> 
> That way, you could tag a headline with something and either apply the
> mapcdi-org-latex-headline-function or the default one (which would
> show the headline).
> 
> #+begin_src
> 
> * headline 1   :done:
> 
> This text would not show a headline since it's complete.
> 
> * headline 2 :inProgress:
> 
> This headline would appear since you're still working on it.
> 
> #+end_src
> 
> Something like that.
> - Or doing the same via todo keywords.
> - Or perhaps a per-subtree definition of the org headline format
> function. If #+bind is allowed as a property at the headline level
> (vs. for the whole file), that would be an easy way.
> 
> I think others like Nicolas who are more familiar with the inner
> workings of the export engine could help you better than I. I'm sure
> it's possible in some manner.
> 
> 
> Good luck,
> John
> 
>> 
>> Is it possible given the current (.emacs/test-file.org) working setup, as a
>> reminder:
>> 
>> ;; change path to point to your org/lisp directory
>> (add-to-list 'load-path "~/.elisp/org.git/lisp/")
>> 
>> (setq org-export-allow-bind-keywords t)
>> 
>> (defun mapcdi-org-latex-headline-function (todo todo-type priority text
>> tags)
>> "The docstring of my function."
>> (concat
>>  (and todo (format "{}" todo))
>>  (and priority (format "{} " ))
>>  (and text (format "{\\vspace{-\\baselineskip}}" ))
>>  (and tags
>>       (format "\\hfill{}\\textit{}" (mapconcat 'identity tags ":")))))
>> 
>> 
>> 
>> 
>> Thanks,
>> 
>> Mark
>> 
>> 
>> 
>> 
>> El 03/09/2013, a las 09:16, mapcdi@me.com escribió:
>> 
>> <LaTeX_output_PDF_ImageCapture.png>
>> 
>> 
>> It works all right!
>> I had org version 7.9 which seems the current 'bundled' version for Emacs,
>> which I recently installed (being a newbie, as I am, for Emacs/Org-mode). I
>> updated via
>> M-x package-install RET org
>> as in http://orgmode.org/org.html#Installation
>> 
>> 
>> and now I have 8.0.7. I compiled with your .emacs/.org example files, except
>> I needed to add:
>> 
>> (setenv "PATH" (concat (getenv "PATH") ":/usr/texbin"))
>>    (setq exec-path (append exec-path '("/usr/texbin")))
>> 
>> or it wouldn't compile the PDF,
>> and there's the output: success!
>> 
>> 
>> So, I will start tinkering myself with some settings like:
>> http://tex.stackexchange.com/questions/39227/no-indent-in-the-first-paragraph-in-a-section
>> 
>> 
>> By the way, do you know how I could eliminate my needed line,  in my .emacs:
>> (setenv "PATH" (concat (getenv "PATH") ":/usr/texbin"))
>>    (setq exec-path (append exec-path '("/usr/texbin")))
>> by way of setting things to a default setting so I don't need to update my
>> path every time via .emacs.
>> 
>> 
>> Thanks!
>> 
>> Mark
>> 
>> 
>> 
>> El 03/09/2013, a las 03:32, John Hendy <jw.hendy@gmail.com> escribió:
>> 
>> 
>> 
>> 
>> On Mon, Sep 2, 2013 at 4:53 PM, <mapcdi@me.com> wrote:
>>> 
>>> <OrgMode_LaTeX_output_PDF_ImageCapture.png>
>>> 
>>> 
>>> 
>>> After I compile:  C-c    C-e    d (… to open PDF file).
>>> It asks:
>>> 'Allow BIND values in this buffer? (yes or no) '
>>> I answer 'yes' and the PDF is opened. I have attached the resulting PDF
>>> screen capture.
>>> Thanks.
>>> 
>> 
>> What is your orgmode version (paste the output of `M-x org-version`)? I
>> decided to just give a whirl with a minimal config and I don't think that
>> Org 8+ asks for allowing bind keywords anymore, or at least it isn't asking
>> me with 8.0.7. From my tinkering, it looks like it ignores them or you need
>> to explictly allow them:
>> 
>> M-x customize-variable RET org-export-allow-bind-keywords RET
>> 
>> Hide Org Export Allow Bind Keywords: Toggle  on (non-nil)
>>    State : CHANGED outside Customize.
>>   Non-nil means BIND keywords can define local variable values. Hide
>>   This is a potential security risk, which is why the default value
>>   is nil.  You can also allow them through local buffer variables.
>> 
>> I could be wrong, but the "toggle" button (vs. stating possible values)
>> implies that it's either on or off.
>> 
>> Actually, in just searching now, it seems that this is, indeed, the case
>> since 8.0.3:
>> 
>> http://orgmode.org/Changes.html#sec-1-5-1
>> 
>> In any case, I am now using this for my minimal config and it works
>> successfully:
>> 
>> #+begin_src
>> 
>> ;; change path to point to your org/lisp directory
>> (add-to-list 'load-path "~/.elisp/org.git/lisp/")
>> 
>> (setq org-export-allow-bind-keywords t)
>> 
>> (defun mapcdi-org-latex-headline-function (todo todo-type priority text
>> tags)
>> "The docstring of my function."
>> (concat
>>  (and todo (format "{}" todo))
>>  (and priority (format "{} " ))
>>  (and text (format "{\\vspace{-\\baselineskip}}" ))
>>  (and tags
>>       (format "\\hfill{}\\textit{}" (mapconcat 'identity tags ":")))))
>> 
>> #+end_src
>> 
>> And this is the file I'm using (I removed anything non-essential to
>> eliminate other possible causes):
>> 
>> #+begin_src
>> 
>> #+options: num:nil
>> #+bind: org-latex-format-headline-function
>> mapcdi-org-latex-headline-function
>> 
>> 
>> 
>> * headline 1
>> 
>> blah blah blah.
>> 
>> * headline 2
>> 
>> blah blah blah
>> 
>> * headline 3
>> 
>> A couple of separate paragraphs to see how far apart two paragraphs would be
>> normally. We'll add enough to line break just to make it interesting.
>> 
>> A couple of separate paragraphs to see how far apart two paragraphs would be
>> normally. We'll add enough to line break just to make it interesting.
>> 
>> #+end_src
>> 
>> 
>> I attached a screenshot of the result!
>> 
>> 
>> Let me know if that helps,
>> John
>> 
>> 
>>> 
>>> My test-file, OrgMode.org:
>>> 
>>> #+TITLE:     My file is OrgMode.org
>>> #+AUTHOR:
>>> #+EMAIL:
>>> #+DATE:
>>> #+DESCRIPTION:
>>> #+KEYWORDS:
>>> #+LANGUAGE:  en
>>> #+BIND: org-latex-format-headline-function
>>> mapcdi-org-latex-headline-function
>>> #+OPTIONS:   H:3 num:nil toc:t \n:nil @:t ::t |:t ^:t
>>> #+OPTIONS:   -:t f:t *:t <:t tasks:nil
>>> #+OPTIONS:   pri:nil tags:not-in-toc
>>> #+OPTIONS:   TeX:t LaTeX:t skip:nil d:nil todo:t
>>> #+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0
>>> path:http://orgmode.org/org-info.js
>>> #+EXPORT_SELECT_TAGS: export
>>> #+EXPORT_EXCLUDE_TAGS: noexport
>>> #+LINK_UP:
>>> #+LINK_HOME:
>>> #+XSLT:
>>> 
>>> * TODO headline 1       :test:
>>> 
>>> blah blah blah.
>>> 
>>> * headline 2
>>> 
>>> blah blah blah
>>> 
>>> * headline 3
>>> 
>>> A couple of separate paragraphs to see how far apart two paragraphs would
>>> be
>>> normally. We'll add enough to line break just to make it interesting.
>>> 
>>> A couple of separate paragraphs to see how far apart two paragraphs would
>>> be
>>> normally. We'll add enough to line break just to make it interesting.
>>> 
>>> 
>>> 
>>> 
>>> ____________________________________________________________________
>>> My .emacs file
>>> 
>>> (custom-set-variables
>>> ;; custom-set-variables was added by Custom.
>>> ;; If you edit it by hand, you could mess it up, so be careful.
>>> ;; Your init file should contain only one such instance.
>>> ;; If there is more than one, they won't work right.
>>> '(adaptive-fill-mode nil)
>>> '(blink-cursor-mode nil)
>>> '(column-number-mode t)
>>> '(current-language-environment "Spanish")
>>> '(debug-on-error t)
>>> '(debug-on-quit t)
>>> '(display-battery-mode t)
>>> '(display-time-mode t)
>>> '(fill-column 56)
>>> '(left-margin 0)
>>> '(ns-alternate-modifier (quote meta))
>>> '(ns-command-modifier (quote super))
>>> '(ns-function-modifier (quote none))
>>> '(ns-right-alternate-modifier (quote none))
>>> '(ns-right-command-modifier (quote left))
>>> '(org-agenda-files (quote ("~/Documents/OrgMode.org")))
>>> '(save-place t nil (saveplace))
>>> '(size-indication-mode t)
>>> '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify)))
>>> '(truncate-lines t))
>>> (custom-set-faces
>>> ;; custom-set-faces was added by Custom.
>>> ;; If you edit it by hand, you could mess it up, so be careful.
>>> ;; Your init file should contain only one such instance.
>>> ;; If there is more than one, they won't work right.
>>> '(default ((t (:inherit nil :stipple nil :background "White" :foreground
>>> "Black" :inverse-video nil :box nil :strike-through nil :overline nil
>>> :underline nil :slant normal :weight normal :height 180 :width normal
>>> :foundry "apple" :family "Monaco"))))
>>> '(set-face-attribute (quote default) nil :height))
>>> 
>>> (setenv "PATH" (concat (getenv "PATH") ":/usr/texbin"))
>>>    (setq exec-path (append exec-path '("/usr/texbin")))
>>> 
>>> (defun mapcdi-org-latex-headline-function (todo todo-type priority text
>>> tags)
>>> "The docstring of my function."
>>> (concat
>>>  (and todo (format "{}" todo))
>>>  (and priority (format "{} " ))
>>>  (and text (format "{\\vspace{-\\baselineskip}}" ))
>>>  (and tags
>>>       (format "\\hfill{}\\textit{}" (mapconcat 'identity tags ":")))))
>> 
>> 
>> <2013-09-02_203154.png>
>> 
>> 
>> 


[-- Attachment #2.1: Type: text/html, Size: 15376 bytes --]

[-- Attachment #2.2: PDF.png --]
[-- Type: image/png, Size: 49186 bytes --]

^ permalink raw reply	[relevance 8%]

Results 1-200 of ~330   | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2013-09-01 21:17     fold paragraphs, export only contents of a node, hiding the 'node heading text' . .
2013-09-01 23:51     ` John Hendy
2013-09-02 16:00       ` . .
     [not found]         ` <CA+M2ft8GPHzEierLmMpJQxtRv=iLQ=dfXXFaqguZmOXi4ykk6A@mail.gmail.com>
     [not found]           ` <C7F63B6F-D5C7-49D5-A7EE-4F0082882901@me.com>
2013-09-03  1:32             ` John Hendy
     [not found]               ` <4702F1A4-113B-4171-B949-2B9EE14EEAA9@me.com>
2013-09-03 14:48                 ` mapcdi
2013-09-03 19:17                   ` John Hendy
2013-09-04  0:20  8%                 ` mapcdi
2014-02-23  9:36     org-entities: why \lang instead of \langle? Anders Johansson
2014-03-13 15:46     ` Bastien
2014-03-25 13:45       ` org-entities: Another issue [was: org-entities: why \lang instead of \langle?] Anders Johansson
2014-03-25 14:02  7%     ` Aaron Ecay
2014-02-28 16:59     Blank page in LaTeX/PDF output Peter Davis
2014-02-28 17:03     ` John Hendy
2014-02-28 17:26  9%   ` Peter Davis
2014-03-01  0:38         ` Nick Dokos
2014-03-01  1:21           ` Peter Davis
2014-03-01  1:30  9%         ` Peter Davis
2014-05-12 13:23  2% Bug: Cannot export this file as HTML. [8.2.6 (8.2.6-18-gaaae4a-elpa @ /home/kuanyui/.emacs.d/elpa/org-20140512/)] kuanyui
2014-11-20 20:37  3% Bug: [Capture] wrongly duplicated date tree outlines [8.2.10] kuanyui
2015-01-06 12:58  4% error in make doc Andreas Leha
2015-03-31 10:26  6% org-mode to latex, again! Sharon Kimble
2015-03-31 15:59  0% ` Marcin Borkowski
2015-04-17 17:28     Resume: Squeezing lines tighter in LaTeX output? Peter Davis
2015-04-17 18:13     ` John Hendy
2015-04-18  0:18       ` Marcin Borkowski
2015-04-18  2:20 13%     ` Peter Davis
2015-04-18  7:02  7%       ` Marcin Borkowski
2015-04-20  8:23  0%       ` Eric S Fraga
2015-05-21 14:40     org-mode, tikz and beamer cédric ody
2015-05-21 18:02     ` Suvayu Ali
2015-05-21 20:33  6%   ` cédric ody
2015-06-24 12:28     Error when exporting LaTeX Peter Davis
2015-06-24 12:45  8% ` Peter Davis
2015-09-03 17:07     merge trees? Matt Price
2015-09-03 17:48     ` Thomas S. Dye
2015-09-03 18:31       ` Matt Price
2015-09-03 19:15  2%     ` Thomas S. Dye
2015-09-14 14:31     CV, org-mode, and pdf Dan Griswold
2015-09-14 15:46 11% ` Eric S Fraga
2016-04-16 13:21  6% exporting to subsubsection not completing Sharon Kimble
2016-08-17  9:46  8% page-numbering in a toc Sharon Kimble
2016-08-17 17:39  0% ` Sharon Kimble
2016-09-29 18:04  9% Making DocBook xml books from org mode? Peter Davis
2016-09-29 19:23  0% ` Joost Kremers
2017-06-10  4:54     How to export LaTeX amsmath align bmatrix to ODT? edgar
2017-06-10  5:13     ` edgar
2017-06-12 21:36 11%   ` edgar
2017-06-14 14:10         ` Nicolas Goaziou
     [not found]           ` <3c4faaee17eb7e7fdd5aea5136742bd5@openmail.cc>
2017-06-25  0:35  5%         ` Fwd: " edgar
2017-06-26 14:16 10% Non-appearance of tables in PDF export under \listoftables Sharon Kimble
2017-06-28 21:47 11% minitocs not displaying in latex export Sharon Kimble
     [not found]     <2535f962381540a18db893c8c5f44f34@HE1PR01MB1898.eurprd01.prod.exchangelabs.com>
2017-07-22 10:44     ` How to wavy/double underline an org-mode link? Eric S Fraga
2017-07-24 13:22  6%   ` Sharon Kimble
2018-03-01 23:09     what settings would make original export to pdf as good as pandoc conversion? Samuel Wales
2018-03-02  7:08     ` Eric S Fraga
2018-03-02 18:53       ` Samuel Wales
2018-03-03 11:26  8%     ` Eric S Fraga
2018-03-08 19:55  0%       ` Samuel Wales
2018-03-09  6:34  0%         ` Eric S Fraga
2018-03-09 20:26  7%           ` Samuel Wales
2018-03-10  0:05  0%             ` Eric S Fraga
2018-03-10  0:30  7%               ` Samuel Wales
2018-03-12  9:42  8%                 ` Eric S Fraga
2018-03-12 23:42                       ` Samuel Wales
2018-03-13  7:21                         ` Eric S Fraga
2018-03-19  4:41  8%                       ` Samuel Wales
2018-03-19  4:48  0%                         ` Samuel Wales
2018-03-19  9:52  7%                         ` Eric S Fraga
2018-03-25  0:23  7%                           ` Samuel Wales
2018-03-26 15:49  2% preview embedded latex fragments error with my settings stardiviner
2018-03-26 15:55  2% stardiviner
2018-09-27  3:30  8% Custom checkboxes when exporting to beamer/latex Adrian Bradd
2018-10-08  9:56     exporting to latex and docx not honouring carriage returns to tabbing Sharon Kimble
2018-10-08 15:54     ` Eric S Fraga
2018-10-09  6:20 10%   ` Robert Klein
2018-10-09 11:06  7%     ` Sharon Kimble
2018-10-09 13:11  0%       ` Eric S Fraga
2018-10-09 16:53  0%         ` Sharon Kimble
2018-10-09 21:31  0%           ` Tim Cross
2018-10-11 13:24  0%             ` Sharon Kimble
2018-10-25 19:14     Help with sharing emacs-org presentation Feiming Chen
2018-10-30  8:42     ` Grant Rettke
2018-10-30 19:01       ` Martin Schöön
2018-10-30 19:43         ` Julius Dittmar
2018-10-31  7:21  3%       ` Eric S Fraga
2018-10-30  5:55     letterhead and signature in odt export Matt Price
2018-10-30  6:54     ` Eric S Fraga
2018-10-30 12:34       ` Matt Price
2018-10-30 13:28         ` Eric S Fraga
2018-10-30 14:29           ` Jeff Filipovits
2018-10-30 15:56  7%         ` ckelty ckelty
2018-10-31  1:26  0%           ` Matt Price
2018-10-31  1:30  6%             ` Matt Price
2018-10-31  3:50                 ` ckelty ckelty
2018-11-01 12:47  4%               ` getting close on latex letterheads [was: letterhead and signature in odt export] Matt Price
2018-10-31 14:53  0%             ` letterhead and signature in odt export John Kitchin
2019-01-29 16:06 10% Definitive answer to org-mode export HTML versus LaTeX Lawrence Bottorff
2019-07-24  7:13     from org to openoffice presentations (or make org looks like openoffice) Luca Ferrari
2019-07-24  7:56     ` Fraga, Eric
2019-07-24 11:42       ` Luca Ferrari
2019-07-24 12:12  6%     ` Fraga, Eric
2019-07-25  7:53  7%       ` Luca Ferrari
2019-07-25  9:16  0%         ` Fraga, Eric
2019-08-26  3:46     [bug] Export to latex truncates long subsections (WE attached) Vladimir Nikishkin
2019-08-26  9:47     ` Nicolas Goaziou
2019-08-27  6:57       ` Vladimir Nikishkin
2019-08-27  7:42  7%     ` Julius Dittmar
2019-08-27  8:10  0%       ` Tim Cross
2019-10-14  7:04     Bug: org-babel-expand-noweb-references is very slow [9.1.9 (release_9.1.9-65-g5e4542 @ /usr/share/emacs/26.3/lisp/org/)] Vladimir Nikishkin
2019-10-14 15:03     ` Nicolas Goaziou
     [not found]       ` <CA+A2iZascDYc2mZfxy_dPSm9f-+_vJ9R+kVdNW_C7MMoOimMnA@mail.gmail.com>
     [not found]         ` <87v9sp9ejl.fsf@nicolasgoaziou.fr>
     [not found]           ` <CA+A2iZZ=gTstVgyzNqi73ysTzRnh5C4GVcmTf6EbEr5mUiRD2w@mail.gmail.com>
     [not found]             ` <87y2ujr198.fsf@nicolasgoaziou.fr>
2020-01-08  2:18  1%           ` Vladimir Nikishkin
2019-12-06  6:47  1% Bug: LaTeX export does not handle .pgf/.tikz images [9.3 (9.3-elpaplus @ .emacs.d/elpa/org-plus-contrib-20191203/)] Arthur
2020-09-15 15:29     basic org questions Emanuel Berg via General discussions about Org-mode.
2020-09-16  0:04  3% ` Tim Cross
2020-09-16  1:58  0%   ` Emanuel Berg via General discussions about Org-mode.
2020-09-16  3:46  8%     ` TEC
2020-09-16  4:11  0%       ` Emanuel Berg
2020-09-16  6:56  0%         ` tomas
2020-09-16  4:13  0%       ` Emanuel Berg
2020-09-16 13:48  8%         ` Eric S Fraga
2020-09-16 16:32  0%           ` Stefan Nobis
2020-09-16 22:53  8%             ` Emanuel Berg via General discussions about Org-mode.
2020-09-16  4:31  0%     ` Tim Cross
2020-09-16 22:11  8%       ` Emanuel Berg via General discussions about Org-mode.
2020-09-16 22:28  0%         ` Tim Cross
2020-09-16 22:31  0%           ` Emanuel Berg via General discussions about Org-mode.
2020-09-16  6:54  0%     ` tomas
2020-09-16  7:37  0%     ` Stefan Nobis
2021-01-22  9:20  8% Dealing with wide labels in description environment Loris Bennett
2021-01-22 11:20  0% ` Juan Manuel Macías
2021-01-22 12:37  0%   ` Loris Bennett
2021-05-28  2:54     Smart quotes not working correctly with single quotes Andreas Gösele
2021-05-28 10:10     ` Juan Manuel Macías
2021-05-28 15:42       ` Andreas Gösele
2021-05-28 17:55         ` Albert Krewinkel
2021-05-28 21:39           ` Andreas Gösele
2021-05-29 21:35  7%         ` Andreas Gösele
2021-08-21 21:58  1% Bug: File variable no longer on first line when running org-id-get-create [9.4.4 (release_9.4.4 @ /usr/share/emacs/27.2/lisp/org/)] Peter Prevos
2022-05-04 15:59  5% [PATCH] New LaTeX code export option: engraved Timothy
2022-05-05  8:48     ` Ihor Radchenko
2022-05-05 15:17  4%   ` Timothy
2022-05-05 16:13  8%     ` Timothy
2022-05-07  5:16           ` Ihor Radchenko
2022-05-07  6:57  3%         ` Timothy
2022-05-07 10:40  3%           ` Timothy
2022-05-07 11:33                 ` Daniel Fleischer
2022-05-08 14:30  2%               ` [PATCH] (v2) " Timothy
2022-05-11 16:05  2%                 ` [PATCH] (v3) " Timothy
     [not found]     <3bc47afb-0bac-f6e8-1097-13dcb6f2be1f@housseini.me>
2022-08-15 18:50  4% ` svg file from tikz picture reza
2022-10-12  3:15     Export of this table fails LuaLaTeX compilation gerard.vermeulen
2022-10-12  4:15     ` Ihor Radchenko
2022-10-12  4:45       ` Max Nikulin
2022-10-12  5:15         ` gerard.vermeulen
2022-10-12  5:55  7%       ` Max Nikulin
2022-10-12  7:26  0%         ` Ihor Radchenko
2022-10-12  8:20  7%           ` Max Nikulin
2022-10-13  2:44  0%             ` Ihor Radchenko
2022-10-12  9:17  0%         ` gerard.vermeulen
2022-10-12 16:21  0%           ` Max Nikulin
2022-10-13  5:03  0%             ` gerard.vermeulen
2022-10-15 21:35     [bug] `org-latex-line-break-safe' breaks the export of verse blocks to LaTeX Juan Manuel Macías
2022-10-16 15:04     ` Max Nikulin
2022-10-16 17:14       ` Line breaks and brackets in LaTeX export (was: [bug] `org-latex-line-break-safe' breaks the export of verse blocks to LaTeX) Juan Manuel Macías
2022-10-17  9:04         ` Ihor Radchenko
2022-10-17 11:30  6%       ` Line breaks and brackets in LaTeX export Juan Manuel Macías
2022-10-17 11:47  9%         ` Ihor Radchenko
2022-10-17 12:27 10%           ` Juan Manuel Macías
2022-10-17 15:01  7%         ` Juan Manuel Macías
2022-10-17 16:46  5%           ` Max Nikulin
2022-10-17 18:04  8%             ` Juan Manuel Macías
2022-10-18  4:41  8%               ` Ihor Radchenko
2022-10-18 14:23  8%                 ` Juan Manuel Macías
2022-10-19  3:57 33%                   ` Ihor Radchenko
2022-10-19  5:11 11%                     ` Max Nikulin
2022-10-19 11:16  7%                       ` Juan Manuel Macías
2022-10-19 12:30                             ` Juan Manuel Macías
2022-10-19 17:07                               ` Max Nikulin
2022-10-20 16:55  6%                             ` Juan Manuel Macías
2022-10-21  3:34  0%                               ` Ihor Radchenko
2022-10-21 16:38 10%                                 ` Max Nikulin
2022-10-21 19:32  0%                                   ` Juan Manuel Macías
2022-10-29  2:36  8%                     ` Ihor Radchenko
2022-11-13 17:01  8%                       ` Max Nikulin
2022-10-18  4:39                 ` Ihor Radchenko
2022-10-19 17:12                   ` Max Nikulin
2022-10-20  5:07                     ` Ihor Radchenko
2022-10-20 17:15  9%                   ` Max Nikulin
2022-10-21  3:41                         ` Ihor Radchenko
2022-10-21 16:32                           ` Max Nikulin
2022-10-22  5:15 11%                         ` Ihor Radchenko
2022-10-22 12:26  0%                           ` Juan Manuel Macías
2022-10-22 15:55 10%                           ` Max Nikulin
2022-11-01  1:51  0%                             ` Ihor Radchenko
2022-11-01 16:07  9%                               ` Max Nikulin
2022-11-02  6:44 11%                                 ` Ihor Radchenko
2022-11-02  6:46  8%                                   ` Ihor Radchenko
2022-11-02 15:27  0%                                     ` Max Nikulin
2022-11-03  6:15 10%                                       ` Ihor Radchenko
2022-11-03 15:00  9%                                         ` Juan Manuel Macías
2022-11-03 15:33 10%                                           ` Max Nikulin
2022-11-04  4:23  0%                                             ` Ihor Radchenko
2022-11-04  5:40  8%                                               ` Max Nikulin
2022-11-05  5:30 11%                                                 ` Ihor Radchenko
2022-11-06  9:42  5% [PATCH] oc-csl: Improve LaTeX bibliography formatting András Simonyi
2022-11-07  2:47  0% ` Ihor Radchenko
2022-11-07 11:15       ` András Simonyi
2022-11-08  5:26         ` Ihor Radchenko
2022-12-11 19:00  4%       ` András Simonyi
2022-12-12  9:07             ` Ihor Radchenko
2022-12-13 16:05               ` Timothy
2022-12-13 19:03                 ` András Simonyi
2022-12-27 22:32  4%               ` András Simonyi
2023-02-07 21:40     [TIP] Exporting Maxima results to LaTeX Leo Butler
2023-02-08 15:43     ` Max Nikulin
2023-02-08 20:40       ` Leo Butler
2023-02-11 11:39 10%     ` Max Nikulin
2023-03-12 12:23     [Pre-PATCH] Overhaul of the LaTeX preview system Timothy
2023-05-26  9:50     ` Rudolf Adamkovič
2023-05-28 17:31       ` Timothy
2023-06-03  9:00  9%     ` Rudolf Adamkovič
2023-04-21 14:00 22% orgtable to latex export \hline[0pt] why? Uwe Brauer
2023-04-22 11:32 18% ` Ihor Radchenko
2023-04-22 12:13 20%   ` Uwe Brauer
2023-04-22 12:32 10%     ` Ihor Radchenko
2023-08-06 12:03 13% [patch] ox-latex.el: fix blank lines behavior in verse block Juan Manuel Macías
2023-08-07 11:40     ` Ihor Radchenko
2023-08-07 17:23       ` Juan Manuel Macías
2023-08-09  7:57         ` Ihor Radchenko
2023-08-09  8:41           ` Juan Manuel Macías
2023-08-10  9:27             ` Ihor Radchenko
2023-08-10 10:39 12%           ` Juan Manuel Macías
2023-08-11 10:00                 ` Ihor Radchenko
2023-08-11 18:52                   ` Juan Manuel Macías
2023-08-12  7:56                     ` Ihor Radchenko
2023-08-14 20:10                       ` Juan Manuel Macías
2023-08-15 10:08                         ` Ihor Radchenko
2023-08-15 11:50                           ` Juan Manuel Macías
2023-08-15 11:53                             ` Ihor Radchenko
2023-08-15 14:25                               ` Juan Manuel Macías
2023-08-16  8:10                                 ` Ihor Radchenko
2023-08-16 14:10                                   ` Juan Manuel Macías
2023-08-17 10:35                                     ` Ihor Radchenko
2023-08-17 20:17 23%                                   ` Juan Manuel Macías
2023-08-23  5:34  8% [BUG] emergency exit [9.6.6 (release_9.6.6 @ /opt/homebrew/Cellar/emacs-mac/emacs-29.1-mac-10.0/share/emacs/29.1/lisp/org/)] Jay Dixit
2023-09-06 14:55     ox-latex language handling in Org-9.5 vs 9.6 Max Nikulin
2023-09-06 22:20     ` Juan Manuel Macías
2023-09-07 11:50       ` Ihor Radchenko
2023-09-07 14:19         ` Juan Manuel Macías
2023-09-07 14:49           ` Max Nikulin
2023-09-08 10:30             ` Max Nikulin
2023-09-08 14:42               ` Juan Manuel Macías
2023-09-08 19:02  2%             ` [patch] Fixes and improvements in org-latex-language-alist (was: ox-latex language handling in Org-9.5 vs 9.6) Juan Manuel Macías
2023-09-09  9:11                   ` Ihor Radchenko
2023-09-09 10:36                     ` [patch] Fixes and improvements in org-latex-language-alist Juan Manuel Macías
2023-09-09 11:33                       ` Ihor Radchenko
2023-09-09 23:59                         ` Juan Manuel Macías
2023-09-10  7:55                           ` Ihor Radchenko
2023-09-10 11:06  2%                         ` Juan Manuel Macías
2023-09-24 21:47  3% [BUG] Previewing equations [9.6.6 (release_9.6.6 @ /usr/share/emacs/29.1/lisp/org/)] Peter Prevos
2023-10-01 15:08     Are 'placement' and 'float' "obsolete terms" in inline images exported to LaTeX? Juan Manuel Macías
2023-10-02 13:10     ` Ihor Radchenko
2023-10-02 14:55       ` Juan Manuel Macías
2023-10-04  9:12         ` Ihor Radchenko
2023-10-04 14:34  7%       ` Juan Manuel Macías
2023-10-06 16:29  0%         ` Ihor Radchenko
2023-10-06 18:35  0%           ` Juan Manuel Macías
2023-11-01  3:43 12% Regression in latex export of tables? Vikas Rawal
2023-11-01  7:32  8% ` Vikas Rawal
2023-11-01 16:41  0% ` Max Nikulin
2023-11-01 23:04 11%   ` Vikas Rawal
2023-11-02  9:29  8%     ` Fraga, Eric
2023-11-03  0:58 11%       ` Vikas Rawal
2023-11-03  2:30  8%         ` Max Nikulin
2023-11-03  3:01  8%           ` Vikas Rawal
2023-12-09  5:18  3% [BUG] ox-odt.el overrides auto-mode-alist defaults [9.6.6 (release_9.6.6 @ /usr/share/emacs/29.1/lisp/org/)] Peter Prevos
2024-01-02 17:20 10% org table export to latex, longtable, code does not compile Uwe Brauer
2024-01-02 17:58  8% ` [SOLVED] (was: org table export to latex, longtable, code does not compile) Uwe Brauer
2024-01-03 14:25     ` org table export to latex, longtable, code does not compile Ihor Radchenko
2024-01-03 15:56 11%   ` Uwe Brauer
2024-01-02 23:46 20% [possible patch] Remove the '\\[0pt]' string from the last line of a verse block in LaTeX export Juan Manuel Macías
2024-01-13 15:08 10% ` Ihor Radchenko
2024-01-13 16:05 18%   ` Juan Manuel Macías
2024-01-13 18:28 20%     ` Ihor Radchenko
2024-01-13 20:22 18%       ` Juan Manuel Macías
2024-01-14 12:33 10%         ` Ihor Radchenko
2024-01-14 21:58 18%           ` Juan Manuel Macías
2024-01-16 14:09 18%             ` Ihor Radchenko
2024-01-16 19:33 18%               ` Juan Manuel Macías
2024-01-17 13:00 17%                 ` Ihor Radchenko
2024-01-17 15:58  9%                   ` Max Nikulin
2024-01-17 17:50 13%                   ` Juan Manuel Macías
2024-01-18 13:05 15%                     ` Ihor Radchenko
2024-01-19 17:28 10%                       ` Juan Manuel Macías
2024-01-20 12:34 10%                         ` Ihor Radchenko
2024-01-20 13:22  9%                           ` Juan Manuel Macías
2024-01-20 13:46  9%                             ` Ihor Radchenko
2024-01-20 15:41  9%                               ` Juan Manuel Macías
2024-01-20 18:47  9%                                 ` Ihor Radchenko
2024-01-20 20:27 18%                                   ` Juan Manuel Macías
2024-01-21 13:42 35%                                     ` Ihor Radchenko
2024-01-21 19:25  9%                                       ` Juan Manuel Macías
2024-01-31 11:39 10%                                       ` Ihor Radchenko
2024-01-21  6:06 18%                                   ` Max Nikulin
2024-01-20 10:09 18%                       ` Max Nikulin
2024-01-20 10:57 10%                         ` Juan Manuel Macías
2024-01-20 12:41  9%                         ` Ihor Radchenko
2024-01-21  5:56 20%                           ` Max Nikulin
2024-01-20 10:27 10%   ` Max Nikulin
2024-01-20 12:35 10%     ` Ihor Radchenko
2024-01-21  5:44  9%       ` Max Nikulin
2024-01-31 15:09  9%         ` Ihor Radchenko
2024-01-29 20:03     An academic journal entirely made in Org-Mode Juan Manuel Macías
2024-01-29 23:16     ` Dr. Arne Babenhauserheide
2024-01-31 14:30  4%   ` Juan Manuel Macías
2024-02-02 11:39  8% figures not exported properly by ox-latex mahmood sheikh
2024-07-09 20:15  0% ` Karthik Chikmagalur
2024-07-11  8:39  0%   ` mahmood sheikh
2024-02-15  9:18 17% [BUG]: elusive vertical white-space errors in engraved source block export gerard.vermeulen
2024-04-11 19:26     [Pre-PATCH] Overhaul of the LaTeX preview system Yaroslav Drachov
2024-04-18 20:04     ` Karthik Chikmagalur
2024-04-18 20:13  9%   ` Yaroslav Drachov
2024-04-29  0:28     [PATCH] lisp/org.el: Obsolete `org-cached-entry-get' in favor of `org-entry-get' Morgan Smith
2024-04-29 16:58     ` Ihor Radchenko
2024-04-29 18:36       ` Morgan Smith
2024-04-30 10:20         ` Ihor Radchenko
2024-05-01 17:14  7%       ` Morgan Smith
2024-05-27 15:07     SMART goals and bolding the first letter Sharon Kimble
2024-05-27 16:21  8% ` Dr. Arne Babenhauserheide
2024-10-24 16:00 10% [BUG] wrong side of point [9.7.13 (9.7.13-8566bc @ /Users/jaydixit/.emacs.d/elpa/develop/org-9.7.13/)] Jay Dixit

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).