在org-mode中,有下标的时候会改变行高,这个可以设置吗?如何才能等高?
改变行高看着就不舒服了。
在org-mode中,有下标的时候会改变行高,这个可以设置吗?如何才能等高?
改变行高看着就不舒服了。
最新版的 org-mode 通过设置变量 org-emphasis-regexp-components 来支持中文行内格式化的方法貌似已经没用了。
Org mode version 9.2.3 (9.2.3-17-g4df705-elpaplus @ /home/james/.emacs.d/elpa/26.2/develop/org-plus-contrib-20190513/)
有同学碰到相同的问题吗?
org-chinese-utils 感觉好像是我写的,后来删库了,现在还能找到?
偶然在 Org-mode 的手册里发现了一个 zero width space,可以解决中文两边必须有空格的问题,同时不会影响展示效果(Spacemacs)。
使用方法:在需要插入空格的地方输入
C-x 8 <RET> zero width space <RET>
在orgmode里开启goto-address-mode
就可以高亮URL了
5年过去了……有更好的解决方案了吗?
我也想知道现在有没有更好的办法解决org-mode中文行内格式化的问题。
最近有了新思路:
先 selection 要 markup 的字段,然后键入相应的 markup 符号,自动在其前后插入 zero width space. 副作用是光标经过 zero width space 时会变细,不过不影响整体美观,操作也比较方便。
;;;###autoload
(defmacro org-surround-markup (&rest keys)
"Define and bind interactive commands for each of KEYS that surround the region or insert text.
Commands are bound in `org-mode-map' to each of KEYS. If the
region is active, commands surround it with the key character,
otherwise call `org-self-insert-command'."
`(progn
,@(cl-loop for key in keys
for name = (intern (concat "unpackaged/org-maybe-surround-" key))
for docstring = (format "If region is active, surround it with \"%s\", otherwise call `org-self-insert-command'." key)
collect `(defun ,name ()
,docstring
(interactive)
(if (region-active-p)
(let ((beg (region-beginning))
(end (region-end)))
(save-excursion
(goto-char end)
(insert ,key)
(insert-char #x200b) ;; Insert zero width space to make inline markup work.
(goto-char beg)
(insert-char #x200b)
(insert ,key)))
(call-interactively #'org-self-insert-command)))
collect `(define-key org-mode-map (kbd ,key) #',name))))
(org-surround-markup "~" "=" "*" "/" "_" "+" "$")
Evil 用户可以用 evil surround 来搞定。
(use-package evil-surround
:after evil
:config
(global-evil-surround-mode 1)
;; Use non-spaced pairs when surrounding with an opening brace.
;; Insert zero width space for org inline markup.
(evil-add-to-alist 'evil-surround-pairs-alist
?\* '("\x200B*" . "*\x200B")
?\+ '("\x200B+" . "+\x200B")
?\/ '("\x200B/" . "/\x200B")
?\~ '("\x200B~" . "~\x200B")
?\= '("\x200B=" . "=\x200B")
?\$ '("\x200B$" . "$\x200B")
?\_ '("\x200B_" . "_\x200B")))
参考:
一个思路:markdown-mode 里面就没有这个问题,可以试着参考 markdown-mode 里面处理特殊格式的机制修改 org-mode 代码。 2012年的时候有讨论这个问题的,当时有人说 org-mode 不再支持 emacs22 之后可以实现这个功能。https://list.orgmode.org/[email protected]/
我也觉得自动加零宽空格是最佳方案 (相对于修改 org-emphasis-regex-components
来说). 我做得更细致一些, 加了些判断:
然后就可以设置中文碰到中文加零宽空格, 西文碰到中文加普通空格, 西文碰到西文也加零宽空格 (因为西文一般都手动输入空格了, 如果没有已经存在的空格, 一般是需要 markup 一个单词的一半的情况, 此时不适合加入空格, 比如如果我要强调 orgmode 是一个 “mode” 那么我可以写 orgmode), 如果原来就已经有空格了就什么都不加. 如果没有选择任何 region, 那么默认要输入的是中文(大部分情况), 然后按照中文内容的逻辑去判断左右是否要加零宽空格/普通空格/啥都不加
现在用得蛮爽的
2021-10-23T00:00:00Z 代码如下(因为有人要). 直接 copy paste了, 写给自己的东西所以肯定有各种不严谨, 但是我一直用得很愉快, 有时候发现有不对的地方也会自己改一下, 但是已经很长时间没动过了, 如果有需要的人也可以自己改. 代码注释大部分是有意义的, 但可能有少部分因为改了代码没改注释所以没意义. 举例来说最开始我只是想写一个对 org 选区进行自动斜体的函数, 因此注释里都说各种“添加 /
”( org 的斜体 markup 符号), 但现在 me/org-emphasize-dwim
这个函数用来添加任意 markup 符号 (/*_+~=
) 都可以.
下面代码中定义了两个非交互函数:
me/non-western-notation-p
:: 自己写的一个对 cursor 前后的字符是否为“中文”(可能更好的说法是“非西文”)进行判定, 这个判定是根据我自己的需要写的. 这个函数在下面的 me/org-emphasize-dwim
中使用me/org-emphasize-dwim
:: 非交互函数, 接受一个参量, 即所要使用的 markup 字符 (/*_+~=
) 中的任意一个, 然后根据选区两端以及两端左右的字符的类型, 添加 markup 符号, 并且分情况添加空格/零宽空格/啥都不加最后有一系列利用 me/org-emphasize-dwim
定义的 emphasize 快捷键, 当然你可以改为自己用的快捷键.
(defun me/non-western-notation-p (str)
"西文以及常用符号的补集, 所谓的“中文”符号判定"
(let ((non-w-notation-regex "[^[:ascii:]éèêàîïµΩçπœ]"))
(cond
((equal str "before")
(if (looking-back non-w-notation-regex)
t nil))
((equal str "after")
(if (looking-at non-w-notation-regex)
t nil))
(t (ding) (message "me/non-western-notation-p 参量错误")))))
(defun me/org-emphasize-dwim (mark)
(let (len-to-cover-until-end
pos-cen-of-pair
start
end)
(if (org-region-active-p) ; 如果有选中文字
(progn
(setq start (region-beginning)
end (region-end))
(goto-char end)
(skip-chars-backward "[:blank:]") ; 跳过所有的 SPC \t 和零宽空格. 注意这里非常非常地 tricky, looking-at/back 中的参量必须是 [[:blank:]], 而 skip-chars-forward/backward 中的参量必须是 [:blank:]
(setq end (point))
(goto-char end)
(when (<= end start)
(ding)
(cl-return-from 'me/org-emphasize-dwim "选区只有空格和零宽空格"))
;; 此时 cursor 在 end 位置, 开始处理右半边
(if (me/non-western-notation-p "before") ; 当左边为“中文”时
(cond
((looking-at "[[:blank:].,:!?;'\"]") ; 当右边为 SPC \t 零宽空格, 或常用的标点符号时
(insert mark) ; 仅仅插入 /
(cl-incf end))
((or (me/non-western-notation-p "after")
(looking-at "\n")) ; 当右边同为“中文”时 (当右边换行, 也假设接下来我们可能在之后继续输入中文)
(insert (concat mark "")) ;插入 / + 零宽空格
(cl-incf end 2))
(t
(insert (concat mark " ")) ; 剩余情况(主要是西文和常用字符), 插入 / + 空格
(cl-incf end 2)))
(cond ; 当左边不为“中文”时 (“西文”以及常用字符)
((looking-at "[[:blank:].,:!?;'\"]") ; 当右边为 SPC \t 零宽空格, 或常用的标点符号时
(insert mark) ; 仅仅插入 /
(cl-incf end))
((or (me/non-western-notation-p "after")
(looking-at "\n")) ; 当右边为“中文”时 (当右边换行, 也假设接下来我们可能在之后继续输入中文)
(insert (concat mark " ")) ;插入 / + 空格
(cl-incf end 2))
(t
(insert (concat mark "")) ; 剩余情况(主要是非“中文”符号)时, 插入 / + 零宽空格
(cl-incf end 2))))
(goto-char start)
(skip-chars-forward "[:blank:]") ; 跳过所有的 SPC \t 和零宽空格
(setq len-to-cover-until-end (- end (point)))
;; 此时 cursor 在 start 位置, 开始处理左半边
(if (me/non-western-notation-p "after") ; 当右为“中文”时
(cond
((looking-back "[[:space:]]") ; 当左边为 SPC \n \t 或零宽空格时
(insert mark)) ; 仅仅插入 /
((me/non-western-notation-p "before") ; 当左边同为“中文”时
(insert (concat "" mark))) ;插入 零宽空格 + /
(t (insert (concat " " mark)))) ; 剩余情况(主要是西文和常用字符), 插入 空格 + /
(cond ; 当右边不为“中文”时 (“西文”以及常用字符)
((looking-back "[[:space:]]") ; 当左边为 SPC \n 或零宽空格时
(insert mark)) ; 仅仅插入 /
((me/non-western-notation-p "before") ; 当左边为“中文”时
(insert (concat " " mark))) ;插入 / + 空格
(t (insert (concat "" mark))))) ; 剩余情况(主要是非“中文”符号)时, 插入 / + 零宽空格
(forward-char len-to-cover-until-end))
(cond ; 当没有区域选中时, 当 markup symbol 为斜体、粗体、中横线时, 直接假设我们接下来要输入的是中文
((or (equal mark "/")
(equal mark "*")
(equal mark "+"))
(cond ; 分情况插入左半边的 mark
((looking-back "[[:space:]]")
(insert mark))
((me/non-western-notation-p "before")
(insert (concat "" mark)))
(t
(insert (concat " " mark))))
(setq pos-cen-of-pair (point))
(cond ; 分情况插入右半边的 mark
((looking-at "[[:blank:].,:!?;'\"]")
(insert mark))
((or (me/non-western-notation-p "after")
(looking-at "\n")) ; 当出现换行符时, 依然假设我们可能会在之后补写中文
(insert (concat mark "")))
(t
(insert (concat mark " "))))
(goto-char pos-cen-of-pair))
(t ; 剩余情况 (markup symbol 为 code 和 verbatim 时), 直接假设我们接下来要输入的是英文
(cond ; 分情况插入左半边的 mark
((looking-back "[[:space:]]")
(insert mark))
((me/non-western-notation-p "before")
(insert (concat " " mark)))
(t
(insert (concat "" mark))))
(setq pos-cen-of-pair (point))
(cond ; 分情况插入右半边的 mark
((looking-at "[[:blank:].,:!?;'\"]")
(insert mark))
((or (me/non-western-notation-p "after")
(looking-at "\n")) ; 当出现换行符时, 依然假设我们可能会在之后补写中文
(insert (concat mark " ")))
(t
(insert (concat mark ""))))
(goto-char pos-cen-of-pair))))))
(define-key org-mode-map (kbd "s-b") (lambda () (interactive) (me/org-emphasize-dwim "*")))
(define-key org-mode-map (kbd "s-i") (lambda () (interactive) (me/org-emphasize-dwim "/")))
(define-key org-mode-map (kbd "s-k") (lambda () (interactive) (me/org-emphasize-dwim "~")))
(define-key org-mode-map (kbd "s-l") (lambda () (interactive) (me/org-emphasize-dwim "_")))
(define-key org-mode-map (kbd "s-=") (lambda () (interactive) (me/org-emphasize-dwim "=")))
(define-key org-mode-map (kbd "s-+") (lambda () (interactive) (me/org-emphasize-dwim "+")))
赞呐,方便分享下你的代码吗?
你可以参考一下这个
好东西,感谢分享!
代码我添加在我的第一个回复里了, 希望对你有用
非常实用,赞啊!
我有个简单的建议,既然zero width space可以用来解决这个问题,为什么不简单的绑定一个输入zero width space的快捷键,然后写orgmode的时候,插入就行了?比如,插入~的时候,直接插入zero width space ~?
像上面那样想办法自动插入不是更省心么
(defun my/insert-zero-width-space ()
(interactive)
(insert-char ?\u200B)) ;; code for ZERO WIDTH SPACE
(global-set-key (kbd “C-x 8 s”) ‘my/insert-zero-width-space)
加空格也很难受。bibtex条目经常是 史永东2021中债估值识别了债券信用风险吗
这种,加了空格就出bug
我的思路是编辑 org 时,一换行就自动进行 search regexp 然后插入分隔符(中英用空格,中中用零宽空格),据此写了个小函数 ingtshan/separate-inline.el: Separating words automatically with given regexp