Jak mogę używać smaku SE Markdown w emacs?

17

Chciałbym użyć smaku SE Markdown w moich emacsach. Domyślny tryb Markdown ma pewne funkcje (backticks i wcięcia, kod #nagłówka, a >także zmienia czcionkę), ale chciałbym również mieć:

  • * zrobić element listy, w tym wcięcie.
  • [foo](http://example.com)pokazać się jako foo i otworzyć przeglądarkę http://example.compo kliknięciu.

Idealnie byłoby, gdybym chciał to pokazać w emacsie jako renderowane Markdown. Na przykład gdybym miał napisać:

## Header

* item 1
* item 2

         while true; do echo foo; done

End of list and more code

    while true; do echo bar; done

 See [here](http://example.com) for details

Chciałbym, aby był renderowany w ten sposób w samym emacsie:


nagłówek

  • przedmiot 1
  • pozycja 2

    while true; do echo foo; done
    

Koniec listy i więcej kodów

while true; do echo bar; done

Zobacz tutaj po szczegóły


Czy można to osiągnąć, a jeśli tak, to w jaki sposób?

terdon
źródło
O renderowanym bloku kodu: czy tryb Markdown nie wyróżnia już bloków kodu? Czego tam szukałeś
Malabarba
Czy chcesz też, aby było to edytowalne, jak edytor WYSIWYG Markdown? Czy wystarczy wyświetlić „skompilowane” wyjście w osobnym buforze? Ten drugi jest raczej prosty, ten pierwszy to gigant kodujący.
Malabarba
@Malabarba, tak, kod jest w porządku. Chciałbym to: i) automatyczne listy wcięć ii) obsługę adresów URL. Albo poprzez, xdg-openalbo nawet po prostu wyświetlając adres docelowy po kliknięciu, ale tekst linku, gdy nie: „Kliknij tutaj ”, aby zostać Click [here](http://example.com)klikniętym. To tylko szybki sposób na płynne dołączanie adresów URL do moich dokumentów tekstowych.
terdon
OK, oba można osiągnąć za pomocą słowa kluczowego font-lock-add-key. Spróbuję coś napisać jutro, jeśli nikt mnie nie pobije.
Malabarba

Odpowiedzi:

19

** EDYCJA: ** Od czasu tego pisania wydaje się, że część funkcji została bezpośrednio zaimplementowana w trybie markdown. Sprawdź ten komentarz i zawarte w nim linki.


Konfiguracja

Istnieją dwa podejścia, które możesz zastosować.

  1. Możesz napisać polecenie, które kompiluje kod przeceny (za pomocą polecenia powłoki) i wyświetla html w buforze.
  2. Możesz wprowadzić pewne modyfikacje w trybie a-la org, aby bufor wyglądał jak renderowany przecena.

Wyjaśniam tutaj, jak zaimplementować numer 2. Po prostu skopiuj cały poniższy kod do pliku inicjującego.

Dodaj reguły blokowania czcionek

Ta zmienna kontroluje wygląd list. Dodaje trochę miejsca do wcięcia listy i używa dość punktora (jeśli twoja czcionka może to wyświetlić).

(defvar endless/bullet-appearance
  (propertize (if (char-displayable-p ?•) "  •" "  *")
              'face 'markdown-list-face)
  "String to be displayed as the bullet of markdown list items.")

To polecenie faktycznie dodaje reguły. Jest jeden dla list i jeden dla linków.

(require 'rx)
(defvar endless/markdown-link-regexp
    "\\[\\(?1:[^]]+\\)]\\(?:(\\(?2:[^)]+\\))\\|\\[\\(?3:[^]]+\\)]\\)"
  "Regexp matching a markdown link.")

(font-lock-add-keywords
 'markdown-mode
 '(("^ *\\(\\*\\|\\+\\|-\\|\\) "
    1 `(face nil display ,endless/bullet-appearance) prepend)
   (endless/markdown-link-regexp
    1 '(face nil display "") prepend))
 'append)

Udostępnij link do edycji

Ponieważ używamy tej displaywłaściwości do ukrywania części linku, musimy powiedzieć blokadzie czcionek, że powinna ona usunąć tę właściwość za każdym razem, gdy usuniesz część linku (w ten sposób nadal możemy go edytować).

(add-hook 'markdown-mode-hook #'endless/markdown-font-lock)

(defun endless/markdown-font-lock ()
  "Configure aggressive font-locking of `markdown-mode'."
  (define-key markdown-mode-map "\C-c\C-l" #'endless/markdown-insert-link)
  (add-to-list (make-local-variable 'font-lock-extra-managed-props) 'display))

Możemy również zdefiniować polecenie do łatwej edycji, powiązane C-c C-l, jak w trybie org.

(defun endless/markdown-insert-link ()
  "Insert or edit link at point."
  (interactive)
  (if (or (looking-at endless/markdown-link-regexp)
          (and (ignore-errors (backward-up-list) t)
               (or (looking-at endless/markdown-link-regexp)
                   (and (forward-sexp -1)
                        (looking-at endless/markdown-link-regexp)))))
      (let ((data (endless/ask-for-link
                   (match-string-no-properties 1) 
                   (or (match-string-no-properties 2)
                       (match-string-no-properties 3)))))
        (if (match-string-no-properties 2)
            (replace-match (cdr data) :fixedcase :literal nil 2)
          (replace-match (cdr data) :fixedcase :literal nil 3))
        (replace-match (car data) :fixedcase :literal nil 1))
    (let ((data (endless/ask-for-link)))
      (insert "[" (car data) "](" (cdr data) ")"))))

(defun endless/ask-for-link (&optional name link)
  (cons (read-string "Text of the link: " name)
        (read-string "URL of the link: " link)))

(Opcjonalnie) Skonfiguruj niektóre twarze

To powinno wystarczyć na punkty, o które prosiłeś. Jeśli chcesz, aby bufor wyglądał jeszcze bardziej jak obniżka SE, zadzwoń

M-x customize-group RET markdown-faces

i zmień to, co uważasz za stosowne. Skonfigurowałem się i oto, co mam.

(custom-set-faces
 '(markdown-header-face-1 ((t (:inherit markdown-header-face :height 2.0))))
 '(markdown-header-face-2 ((t (:inherit markdown-header-face :height 1.7))))
 '(markdown-header-face-3 ((t (:inherit markdown-header-face :height 1.4))))
 '(markdown-header-face-4 ((t (:inherit markdown-header-face :height 1.1))))
 '(markdown-inline-code-face ((t (:inherit font-lock-constant-face :background "gainsboro"))))
 '(markdown-link-face ((t (:inherit link))))
 '(markdown-pre-face ((t (:inherit font-lock-constant-face :background "gainsboro")))))

Wyniki

Oto, co otrzymasz po pierwszych 2 zestawach konfiguracji:
wprowadź opis zdjęcia tutaj

Oto, co otrzymasz po skonfigurowaniu twarzy. Można się spierać, czy to wygląda lepiej, ja osobiście trzymam się powyższego.
wprowadź opis zdjęcia tutaj

Malabarba
źródło
Łał! To prawie idealne, dzięki. To odpowiada na wszystko, o co prosiłem, ale jeśli chcesz uzyskać dodatkowe punkty brownie, czy istnieje sposób, aby link był bardziej interaktywny? Mam na myśli prosty sposób na wyodrębnienie adresu URL. Czy można przełączać się między [foo]i [foo](http://bar.com)klikając? Nie przejmuję się szczegółami, ale w razie potrzeby chciałbym w prosty sposób wyświetlić adres URL. W tej chwili muszę usunąć jeden z nawiasów, aby się pojawił. Mogę z tym żyć, ale byłbym zainteresowany w lepszy sposób.
terdon
@terdon Gotowe! ..
Malabarba
Zamierzam połączyć to z Edycją z Emacsem , a następnie przejdę obszar trójstanowy!
nispio
@Malabarba wydaje się, że jest tam błąd. Mam "Unknown rx form grupę n '” . Output of --debug-init` tutaj Wszelkie pomysły.?
terdon
@terdon Możliwe, że grupa-n jest zdefiniowana tylko w 24.4, spróbuję to sprawdzić. Możesz spróbować wymienić każdy z nich na group-n X just group. To może nadal działać.
Malabarba
5

Dobrym miejscem na początek byłoby markdown-mode.elpobranie go stąd .

Ten tryb nie oferuje org-modeupiększania stylu, ale oferuje podświetlanie składni i szereg customizeopcji.

Aby uzyskać upiększenie tego stylu, ktoś musiałby napisać rozszerzenie do markdown-mode.el implementującego font-face.

  • Większość twarzy org-mode.el jest zdefiniowanych w org-faces.el .

  • Dodatkowo przyjrzyj się, jak tryb org wizualnie zamienia tekst na znaki. Ten kod znajduje się w org-podmiotów.el . Jest to kod, który zamienia lateks na \pm±.

Nixeagle
źródło
Dzięki, w tej chwili korzystam z trybu przeceny, jak wspomniałem w mojej odpowiedzi. Chciałbym wiedzieć, jak zaimplementować brakujące funkcje, a także jak wyświetlać emacs jako renderowane. Ewentualnie chciałbym wiedzieć, że w takim przypadku nie można wyświetlić ich renderowanych.
terdon
Można to zrobić, tryb org wykonuje takie upiększanie składni. Daj mi chwilę, aby znaleźć kod. Zrobiłem podobne kodowanie dla innego trybu głównego. Nie zdawałem sobie sprawy, że wiesz już o markdown.el.
nixeagle
Zredagowałem odpowiedź, aby zapewnić sposób na robienie tego, co chcesz. Kiedy wrócę do domu, być może uda mi się stworzyć kod, który robi dokładnie to, co chcesz. W tej chwili org-mode modyfikuje tytuły, aby ukryć *oznaczające poziomy i zmienia rozmiar tytułu w zależności od tego, gdzie jest w dokumencie. Jest także w stanie ładnie formatować linki.
nixeagle