dtk01 / dtk

Read the Bible or other diatheke-accessible material in emacs
GNU General Public License v3.0
24 stars 10 forks source link

Is it possible to use dtk as highlighter/lexer? #11

Closed vonpupp closed 4 years ago

vonpupp commented 4 years ago

Hello,

I am not yet very fluent in emacs. I am working on the translation of several bible studies and I often quote verses. Since DTK already has a mode I was wondering if it is possible to highlight text passages using the DTK mode. Let me try to explain better my idea.

I already implemented something similar using latex sty templates as follows:

#+ATTR_LATEX: :options {1 Joao 3:4}
#+begin_scripture
4 Todo aquele que pratica o pecado transgride a Lei; de fato, *o pecado é a
transgressão da Lei*.
#+end_scripture

Which in conjunction with this sty snippet:

\newenvironment{scripture}[1]{%
\stepcounter{ScriptureCount}
  \begin{adjustbox}{minipage=[b]{380px},margin=1ex,fgcolor=119Blue,env=center}%
\textbf{\textcolor{black}{#1}}\\%
}{%\\
%\center{\textcolor{black}{Escritura \theScriptureCount}}
  \end{adjustbox}%
}

Renders this in PDF: 2020-01-19-102128_2720x1024_scrot

However the problem of this approach is that renders the "options" parameter only in PDF (since it is a latex template, which makes sense). In html it renders as follows:

<div class="scripture">
<p>
4 Todo aquele que pratica o pecado transgride a Lei; de fato, <b>o pecado é a
transgressão da Lei</b>.
</p>
</div>

Which doesn't include "1 John 3:4", nor the possibility to define a css style for verse numbers.

Idealy I would like to have something like this:

#+begin_src bible :exports results
quote("1 John 3:4", "1 João 3:4")
#+end_src

#+RESULTS:
1 João 3:4:
(4) Todo aquele que pratica o pecado transgride a Lei; de fato, *o pecado é a
transgressão da Lei*.

Which should render to something like this:

<div class="passage">1 João 3:4:</div>
<div class="scripture">
<p>
<div class="verse">4</div> Todo aquele que pratica o pecado transgride a Lei; de fato, <b>o pecado é a
transgressão da Lei</b>.
</p>
</div>

Then the results section can be tweaked to add further styles, like bold parts, etc.

I guess not all these functionalities are present in DTK, but I wonder if you could you please point me into the right direction to achieve this?

Thank you.

yiufung commented 4 years ago

It seems a structural output would help in this case. For example, if dtk may return an alist, where car is the key such as :book, :chapter, :verse and cdr be the value, then user can write customized function to style different parts. However, it's still difficult for me to picture how emphasizing a region could work under this case: How do we locate the part where user wish to emphasize?

Moreover, even such an alist exist, styling it would be a task of org-export related modules. I'd suggest you take a look at CSS Support, which let you redefine css style. For example:

* John 3:16
:PROPERTIES:
:HTML_HEADLINE_CLASS: passage
:HTML_CONTAINER_CLASS: scripture
:CUSTOM_ID: verse_id
:END:
For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life.

would generate:

<div id="outline-container-org56be8b3" class="outline-2 scripture">
<h2 id="verse_id" class="passage"><span class="section-number-2">1</span> John 3:16</h2>
<div class="outline-text-2" id="text-verse_id">
<p>
For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life.
</p>
</div>
</div>

However, I couldn't find a way to get rid of h2 tag here. (Another point of customization. Perhaps there's someway to override it in CSS? Perhaps you can add a post-hook that turn all h2 class='passage' into div? I don't know)

And it seems to me you're trying to export to both LaTeX and HTML. In many cases, they may accept different attribute parameters. You need to decide for yourself a set of options that work for both. Writing the same option lines repeatedly in your document would be very difficult to manage. Perhaps you'd be interested in putting it in a customized function my_quote, and then use #+CALL as specified in Evaluating Code Blocks. For example, use

#+CALL: my_quote("John", 3, 16)

to quote your verse.

It's just a brainstorm here. Org has a universe of possibilities, hope you find an easy path that works for you.

vonpupp commented 4 years ago

Thank you very much!

A lot of new information to digest. I will evaluate your suggestions.

I also thought about some of the following ideas:

Highlighting with Pygments for Org-mode Src Blocks, or writing a lexer, however I am not sure how they will play out in both HTML and PDF.

I also though of writing a python script to parse the output of diatheke directly using OSIS XML as output, so I can format the data according to my needs. With this idea I am thinking of executable blocks, so only the bible reference and C-c C-c would be needed to yield the verse. Plus I could have global parameters like the sword module translation to use. Of course this is just an idea.

Thanks again! Congratulations on DTK, it is very useful!

thomp commented 4 years ago

@vonpupp I am hoping to better understand what exactly you envision in terms of functionality. Are you hoping to have a way to obtain a "parsed version" of a given diatheke text programmatically? If so, the existing functionality can readily be modified to do this (e.g., see https://gist.github.com/thomp/776330d4873a19cfcbb8fee6ed7bed3b ).

Or are you hoping to do something along the lines of "browsing" a text using dtk-mode, and then, with the existing text present in the buffer, select a region of text and invoking a function (M-x dtk-export-to-org-latex ? ) "export" the selected text to an org-friendly or LaTeX-friendly format? If so, this would require a different approach but shouldn't be particularly difficult as a bit of metadata is embedded in the dtk buffer via text properties. For example, typically any word in a given Biblical text will have at least the book, chapter, and verse data present as text properties -- e.g.,

book "Hebrews" chapter 10 dict ("266" "StrongsGreek") fontified t verse 3

Given this, it would be relatively straightforward to "word backwards" and construct a tree describing any given selected region in a dtk buffer. That object could then be used to generate HTML, LaTeX, or whatever...

vonpupp commented 4 years ago

@thomp, thank you for your message and sorry for the delay.

I made a video a while ago and even it was not made for this purpose (rather to share it with non technical people), it might help to illustrate more of what I am doing and where I want to go. What I am writing here refers to the minute 2:20 until approx 4:05. I am not using dtk for browsing, I am using the dtk-bible function to paste in place the verses, let me try to elaborate.

During the translation process I get to a point where I have the verses I should quote, like this: "Apocalipse 14:6-7"

I manually expand (1) the 'scriptures' yasnippet template which yields this:

#+ATTR_LATEX: :options {}
#+begin_scripture
#+end_scripture

Then I include (2) the verse between the '{}' section and then I invoke (3) dtk-bible manually which yields this:

#+ATTR_LATEX: :options {Apocalipse 14:6-7}
#+begin_scripture
6 Então vi outro anjo, que voava pelo céu e tinha na mão o *evangelho eterno* para
proclamar aos que habitam na terra, a toda nação, tribo, língua e povo. 7 Ele
disse em alta voz: "Temam a Deus e glorifiquem-no, pois chegou a hora do seu
juízo. Adorem aquele que fez os céus, a terra, o mar e as fontes das águas".
#+end_scripture

So far it is working great and I got pretty much used to this workflow. Then I realize that when I exported to HTML I didn't get the reference, since it was only exported to latex. This is not such a big deal, but in the future I could need to export to HTML and need to work on that.

What I am looking for is to try to automate as much as possible the process of: (1) expand (2) include and (3) invoke, so I can translate faster.

Some considerations that would be nice to have if possible:

These are just ideas. What I would like is to try to be faster on the process, but if none of these are possible that is fine, I will keep doing it manually.

Thank you very much to you both for your kindness and willing to help me out.

If any of you need to view the repository, please let me know and I can invite you to view it, is it in gitlab though.

thomp commented 4 years ago

It seems like this is a wish-list of quite a few different things -- some of which might merit modifications of dtk and others which might be best accomplished through other approaches.

With respect to your comment "it would be nice to be able to set a default translation but also to modify it if needed", one may set dtk-module programatically or via invoking dtk-select-module. What is the drawback to this approach?

With respect to your interest in "[trying] to automate as much as possible the process of: (1) expand (2) include and (3) invoke", one can arbitrarily redefine dtk-insert-verses as desired -- it is passed the parsed content and can handle it in whatever manner is desirable. Perhaps something like the modified version below might be a good starting point for a klunky one-off "solution" for your situation?

Is the broader question one of whether it is desirable to make things more configurable with the default DTK-INSERT-VERSES function? In your use case, the desired configurability seems to be in facilitating the ability to a) customize/define insertion of content that precedes the verse texts themselves, b) customize/define insertion of content that succeeds the verse texts, and c) customize the formatting the verse numbers. Is this correct?

;;; modified to insert content before/after insertion of verses themselves
(defun dtk-insert-verses (verse-plists)
  "Insert formatted text described by VERSE-PLISTS."
  (setf dtk-debug-verse-plists (copy-list verse-plists))
  (cl-flet ()
    (let ((this-chapter nil))
      ;; handle first verse
      (-let (((&plist :book book :chapter chapter :verse verse :text text) (pop verse-plists)))
    ;;
    ;; insert special stuff at the beginning
    (insert "#+ATTR_LATEX: :options {")
    (insert book " " (int-to-string chapter) ":" (int-to-string verse))
    ;; insert -nn if it's a verse range
    (when verse-plists
      (-let (((&plist :book book :chapter chapter :verse verse :text text) (first (last verse-plists))))
        (insert "-" (int-to-string verse))))
    (insert "} " #xa)
    (insert "#+begin_scripture" #xa)
    (dtk-verse-inserter book chapter verse text
                ;; not desirable
                nil nil ;t t
                )
    ;; end special stuff at the beginning
    ;;
    (setf this-chapter chapter))
      (cl-loop
       for verse-plist in verse-plists
       do (-let (((&plist :book book :chapter chapter :verse verse :text text) verse-plist))
        (if (equal chapter this-chapter)
        (progn
          (unless (member (char-before) '(#x20 #x0a #x0d))
            (insert #x20))
          (dtk-verse-inserter book chapter verse text nil nil))
          ;; new chapter
          (progn
        (insert #xa #xa)
        (setf this-chapter chapter)
        (dtk-verse-inserter book chapter verse text nil t)))))
      ;;
      ;; insert special stuff at the end
      (insert #xa)
      (insert "#+end_scripture" #xa)
      ;; end special stuff at the end
      ;;
      )))
thomp commented 4 years ago

There is a bit more flexibility now with verse insertion via dtk-insert-verses-pre, dtk-insert-verses-post, and dtk-verse-number-inserter. Perhaps I'm still not understanding what you're looking for but it seems like the flexibility these offer might allow for a bit more efficiency with your work flow -- e.g.,

;; Work in arbitrary buffer
(setf dtk-buffer-p nil)
;; Special content before inserting verses
(setf dtk-insert-verses-pre
      (lambda (book chapter verse verse-plists)
    (insert "#+ATTR_LATEX: :options {")
    (insert book " " (int-to-string chapter) ":" (int-to-string verse))
    ;; insert -nn if it's a verse range
    (when verse-plists
      (-let (((&plist :book book :chapter chapter :verse verse :text text) (first (last verse-plists))))
        (insert "-" (int-to-string verse))))
    (insert "} " #xa)
    (insert "#+begin_scripture" #xa)))
;; Special content after insertion of verses.
(setf dtk-insert-verses-post
      (lambda ()
    (insert #xa)
    (insert "#+end_scripture" #xa)))
;; Format verse number
(setf dtk-verse-number-inserter
      (lambda (verse-number)
    (insert #x2f (int-to-string verse-number) #x2f #x20) ; wrap with /
    ))
dtk01 commented 4 years ago

Closing since this seems resolved.