“自动将小节标题转换为标题大小写”的用户脚本

“自动将小节标题转换为标题大小写”的用户脚本

我想编写一个 Texstudio 宏(脚本),扫描整个.tex文件并将所有指令内的文本转换\subsection{}为标题大小写。

\subsection{this is the title of this subsection}

\subsection{This Is the Title of This Subsection}

我第一次尝试这种脚本编写。

答案1

正如我之前的评论中提到的,TeXstudio 有一个内置的“转换为标题大小写”功能Edit -> Text Operations -> To Titlecase,这意味着不需要 (1) 使用 TeX 进行复杂的“黑客攻击”,以及 (2) 按照其他答案考虑标题大小写的特定“用例”。

toolbar invoking

我们可以在 TXS 用户宏中调用此函数,我相信这正是 OP(最初)寻找的。

免责声明:

我并不声称下面的脚本是经过精心打磨并适用于所有用例(事实并非如此!)。我也不确定app.editTextToTitlecaseSmart()函数的具体工作原理,但从我迄今为止的测试来看,它似乎运行良好,即使在小节标题中使用首字母缩略词(参见示例 1)。TXS 手册在此处提供了有关标题格式的一些信息:http://texstudio.sourceforge.net/manual/current/usermanual_en.html#SECTION15

以下脚本已在 TXS 2.12.6 中测试。与 TXS 中的所有宏一样,函数名称(即app.editTextToTitlecaseSmart()等)将来可能会被开发人员更改,因此下面显示的宏可能不起作用适用于 TXS 的未来版本 (>2.12.6)。

使用注意事项:

  • 确保\subsection{...}命令按照下面的示例占据自己的行。我认为唯一的例外是放在调用\label{..}之后\subsection(参见示例 1)。

  • 我假设您希望将该小节的简称(如果存在)也转换为标题大小写。(参见示例 2)。

  • 请始终再检查一遍如果用户宏在调用后转换正确完成。代码在弹出的对话框中提供了“脚本报告”,以便您可以查看已更改的内容——电话号码标题已转换为标题大小写。

    如果您对我的代码有信心(!!)并且想要禁用脚本报告弹出窗口,那么您只需注释/删除代码的最后一行:information(str);

  • 这种方法的一个潜在缺点是您将无法为标题创建例外(我认为),因为这一切都是由app.editTextToTitlecaseSmart内部函数完成的。

“自动将小节标题转换为标题大小写”的用户脚本

设置宏

  1. 从主工具栏转到Macros -> Edit Macros
  2. 点击Add +弹窗左下角的,添加新的用户脚本。
  3. LaTeX content将以下内容粘贴到弹出窗口右侧的大框中:

    %SCRIPT
    /*  Note: Comment/Delete the last (optional) line if you 
        do not want the script report.
    */
    
    var tl = editor.document().textLines();
    var regEx = /\\subsection(\[.*\])*(\{((?!\\label).)*\})/;
    var str = "Script Report:\n\n";
    var match, scope, matchTC;
    
    function titlecase(c){
        editor.setCursor(c);
        app.editTextToTitlecaseSmart();
    }
    
    for (var i=0;i<tl.length;i++){
        match = regEx.exec(tl[i]);
        scope = editor.document().cursor(i, 0, i);
        // Titlecase the short titles [...]
        if (match && match[1]){
            editor.search(match[1], scope, titlecase)
            matchTC = cursor.selectedText();
            str += 'L' + (i+1).toString() + ' :: ' + matchTC + '\n';
        }
        // Titlecase the long titles {...}
        if (match && match[2]){
            editor.search(match[2], scope, titlecase)
            matchTC = cursor.selectedText();
            str += 'L' + (i+1).toString() + ' :: ' + matchTC + '\n';
        }
    }
    editor.selectNothing();
    information(str) // optional
    

pasting

测试宏

一些测试用例:

这些是我测试过的例子。

% Example 1: With label at the end + Acronyms not affected
\subsection{this should be in titlecase: NASA in a nutshell}\label{subsec:title}

% Example 2: Short titles also to be title-cased
\subsection[short titles]{capitalized every word except of the not needed in such cases}
\label{LabelOnANewLine}

% Example 3: Smart title-casing
\subsection{you can't {{{{escape}}}} 2!!}

% Example 4: Non-examples
\chapter{not this one}
\section{not this one too}
Normal text should not get affected as well.

% Example 5: Obscure example in a verbatim environment...
\verb|\subsection[the last example]{The last example in a long time...}|

动图:

gif working

答案2

根据@Mico 的要求编辑

这是一个答案旧:(但我不知道) 新的:(我知道的)它在 TeXstudio 中工作:

\documentclass{article}
\usepackage{mfirstuc}
\usepackage{fancyhdr}
\usepackage{lipsum}
\MFUnocap{a} %We have to give the words we don't want to be automatically capitalized
\MFUnocap{non}
\MFUnocap{be}
\MFUnocap{of}
\MFUnocap{the}
\MFUnocap{in}
\MFUnocap{for}
\MFUnocap{etc}
\let\oldsubsection\subsection
\makeatletter
\def\subsection{%
\@ifstar{\@Starred}{\@nonStarred}%
}
\def\@Starred{%
\@ifnextchar[%
{\GenericWarning{}{Warning: A starred section can not have parameters. I am going to ignore them!}\@StarredWith}%
{\@StarredWithout}%
}      
\def\@StarredWith[#1]#2{%
\oldsubsection*{\capitalisewords{#2}}%
}
\def\@StarredWithout#1{%
\oldsubsection*{\capitalisewords{#1}}%
}
\def\@nonStarred{%
\@ifnextchar[%
{\@nonStarredWith}%
{\@nonStarredWithout}%
}
\def\@nonStarredWith[#1]#2{%
\oldsubsection[\capitalisewords{#1}]{\capitalisewords{#2}}%
}
\def\@nonStarredWithout#1{%
\oldsubsection{\capitalisewords{#1}}%
}
\makeatother

\begin{document}
\pagestyle{fancy}
\tableofcontents
   \section{test a non capitalized title}
   \lipsum[1-2]
   \subsection{this will be a capitalized simple subsection title}
   \lipsum[1-5]
   \section{non capitalized}
   \lipsum[1]
   \subsection[a capitalized toc and header title for now]{Capitalized every  word except of the not needed in such cases}
   \lipsum[1-11]
   \subsection*{a capitalized title}
   \lipsum[1-3]
   \subsection{capitalized a last title etc}
   \lipsum
\end{document}
\end{document}

您必须添加包并包含之后和之前的msfirstuc行。\usepackage{lipsum}\begin{document}

输出:

enter image description here

enter image description here

enter image description here

这是我在这里的一个旧答案:https://tex.stackexchange.com/a/378568/120578这对小节进行了更改并且不再使用 koma-script。

编辑:PS(忽略@AlanMunn 提到的):如果无法导入 TeXStudio,请随时要求我删除它。

答案3

这是一个基于 LuaLaTeX 的解决方案。它首先将 的强制参数和可选参数(如果存在)中所有单词开头的小写字母大写\subsection。然后对单词“the”、“of”和“a”进行例外处理。

唯一的输入要求是字符串\subsection、方括号中的可选参数(如果存在)和花括号中的强制参数都在一行上 - 不允许换行。我相信这不是一个约束。

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}

\usepackage{luacode} 
\begin{luacode*}
function my_upper ( z )
   -- First, uppercase all starting lowercase letters ('%l' in Lua jargon)
   -- "starting": %l is preceded by whitespace, {, or [
   z = z:gsub ( "[%s{%[]%l" , string.upper )
   -- Next, undo upper-casing for "of", "the" and "a"
   z = z:gsub ( " Of " , string.lower ) 
   z = z:gsub ( " The ", string.lower )
   z = z:gsub ( " A "  ,  string.lower )
   return z
end
function do_subsec ( s )
   s = s:gsub ( "\\subsection%s*%b[]%s*%b{}", my_upper )
   s = s:gsub ( "\\subsection%s*%b{}", my_upper )
   return s
end
\end{luacode*}
\AtBeginDocument{\directlua{luatexbase.add_to_callback(
   "process_input_buffer", do_subsec, "do_subsec" )}}

\begin{document}
\section{this is the title of a section}
\subsection{this is the title of a subsection}
\subsubsection{this is the title of a subsubsection}
\bfseries hello world
\end{document}

答案4

这个问题可以用 TeX 原语来解决:

% \def\subsection{{\bf#1}\par} %< use this if you are not using LaTeX (like me)  

% code from OPmac:
\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\isinlist#1#2#3{\begingroup \long\def\tmp##1#2##2\end{\def\tmp{##2}%
   \ifx\tmp\empty \endgroup \csname iffalse\expandafter\endcsname \else
                  \endgroup \csname iftrue\expandafter\endcsname \fi}%
   \expandafter\tmp#1\endlistsep#2\end
}

\let\ssecOri=\subsection
\def\subsection#1{\def\tmp{}\docapA#1 {} \expandafter\ssecOri\expandafter{\tmp}}
\def\docapA#1#2 {%
   \ifx^#1^\else
      \ifx\tmp\empty\else \addto\tmp{ }\fi
      \isinlist\exceptions{,#1#2,}\iftrue 
         \addto\tmp{#1#2}%
      \else
         \uppercase{\addto\tmp{#1}}\addto\tmp{#2}%
      \fi
   \expandafter\docapA\fi
}
\def\exceptions{,a,non,be,of,the,in,for,etc,}

% test:
\subsection{this will be a capitalized simple subsection title}

\bye

相关内容