• <em id="6vhwh"><rt id="6vhwh"></rt></em>

    <style id="6vhwh"></style>

    <style id="6vhwh"></style>
    1. <style id="6vhwh"></style>
        <sub id="6vhwh"><p id="6vhwh"></p></sub>
        <p id="6vhwh"></p>
          1. 国产亚洲欧洲av综合一区二区三区 ,色爱综合另类图片av,亚洲av免费成人在线,久久热在线视频精品视频,成在人线av无码免费,国产精品一区二区久久毛片,亚洲精品成人片在线观看精品字幕 ,久久亚洲精品成人av秋霞

            個性分組符號(個性分組符號怎么打)

            更新時間:2023-03-02 17:44:11 閱讀: 評論:0

            話題:#科技# #數學# #計算機語言# #LaTeX#

            小石頭/編

            TeX在原子命令的執行上是嚴格按照順序的,但是宏的展開卻允許在順序的基礎上進行微調,這樣做的因為是:宏展開相當于程序員編寫代碼的過程,對于程序員來說,只能是大部分時間按順序coding,但有時會返回修改或暫時跳過。

            在前面章節中,我們已經接觸過二種調節展開順序的用例,

            保證尾遞歸:

            defcs{ ... el ... expandafter cs fi}

            通過 expandafter 使得 fi 先展開,而 fi 展開為空,于是 cs 就到了自己的尾部。

            阻止定義時(高速模式)展開:

            oks77={cmd}edefcs{ oexpand cmd he oks77}

            命令 oexpand 會阻止 cmd 在cs的定義時展開, he會取出 oks77的內容cmd,但不會做進一步展開。

            命令執行優先級,其實也需要改變了 執行順序,考慮如下命令復合代碼,

            defa#1.{a[#1]} def#1.{b(#1)}a  x.. % => a[b(x])

            輸出結果出錯了!這顯然不是命令復合的本意,我們想要的結果是 ①

            a[b(x)]

            分析原因:第二行,由于 a 先被執行 所以  x 成了它的參數,于是展開為(注意:命令會吃的后面的空格),

            a[ x].

            接著被展開,x]匹配為它的參數,于是最終展開為,

            a[b(x])

            要修復這個BUG就要  先于 a 展開。這在其它 語言里,可以使用 括號 來調整表達式的優先級,但是TeX沒有這個機制。不過可以使用 分組來 替代,第二行可改為,

            a { x.}.

            這次在a展開時,參數變成了一個分組 { x.},于是展開為,

            a[{ x.}]

            然后是再以x為參數展開,得到 ②,

            a[{b(x)}]

            最后,執行展開結果,分組符號不會輸出,最終結果為就是①了。

            這里必須注意,②和① 是有區別的,也即是說,在使用 分組調節優先級的同時引入了分組。若想要展開的直接結果就是 ① ,可以這樣,

            expandafter a  x..

            命令 expandafter 保持  先于 a 被展開一次,它匹配參數是 x,于是展開為,

            a b(x).

            接著,a再以 b(x) 為參數,展開就是 ①了。

            在一般情況下 ① 和 ② 并差別,可是在 let 命令中,就會不同。考慮用 csname命令來產生命令名,例如:

            letcsname zeroendcsname=0 % ! Extra endcsname.

            出錯了!原因是 let 將 csname 當成了要復制的命令,而由于 = 可是省略,所有實際上是將 字符 z 賦值給了 csname,之后 ero 不展開,然后到endcsname 由于找不到 與之匹配的 csname 于是就多了出來 。

            解決這個問題,就是要讓 csname 先于 let 被執行。此時如果使用 分組,

            let{csname zeroendcsname}=0 % ! Missing control quence inrted.

            則不行了,原因是分組并不是命令不能被賦值。而使用 expandafter,

            expandafterletcsname zeroendcsname=0zero % => 0

            就沒有問題了!

            def 與 let 類似,例如:

            defcsname zeroendcsname{0}zero % ! Undefined control quence.

            出錯了,原因是 第一行等于 重新定義了 csname。解決這個問題,同樣需要使用 expandafter,

            expandafterdefcsname zeroendcsname{0}zero % ! % => 0

            OK!

            直到現在,我們使用宏來生產代碼都是,句法級別的,也就是以 標記(token)為單位的,而宏還可以深入到,詞法級別,也就是可以分拆和組合命令名。

            分拆命令名:

            TeX 提供 命令 string 將 命令 轉為 命令名字符串,例如:

            string cs % => cs

            但是之前會帶有 轉義符 ,這時可以寫一個 單參數 空命令,吃掉它,

            expandafter ail string cs % => cs

            然后,將這個功能包成一個宏,

            defuncsname#1{expandafter ailstring #1}uncsnamecs % => cs

            我們就完成了分拆命令名的第一步,取出命令名。

            接下就可以使用帶定界符的宏進行模式匹配,進一步分析命令名。

            組合命令名:

            這個我們已經知道了就是 csname 命令,有三類對象和相互組合:

            ⑴ 立即字符:

            defvalue{abc}expandafterletcsname abcendcsname=value

            ⑵ 宏:

            def ame{b}expandafterletcsname a ame cendcsname=value

            ⑶ 標記列寄存器:

            oks77={b}expandafterletcsname a he oks77 cendcsname=value

            注:宏命令 char n 可以產生單個編碼是n的字符,而 ^^n 可產生編碼是 n±127 的字符。

            好了,關于詞法宏,的機制也就這么多了,下面舉個栗子。

            考慮,前文提到過的, TeX 生成標記的命令,

            ewififabc

            實際上,TeX僅僅為我們添加如下兩行代碼 ③,

            defabctrue{letifabc=iftrue}defabcfal{letifabc=iffal}

            這 功能上很簡單,因此要實現 ewif 命令的關鍵是 從 ifabc 命令名中 解析出 abc ,再由 abc 組成出abctrue、abcfal 和 ifabc 三個命令。實現分析:

            解析出abc,

            考慮 使用 uncmd 可從 ifabc 先 中 解析出 ifabc,然后再使用 兩次 tail 分別吃掉 if 就剩下了 abc,具體代碼如下:

            edefflag{uncsnameifabc}edefflag{expandafter ailflag} edefflag{expandafter ailflag}flag % => abc

            值得一提:由于 expandafter 也是宏,于是可以被自己作用自己 用以達到 排序效果,例如上面的第二、三行代碼可以改寫為:

            edefflag{expandafterexpandafterexpandafter ailexpandafter ailflag}

            是不是很酷!

            定義命令,

            這個并不難,但要搞清,定義時 和運行時,(以 abctrue 為例)代碼如下:

            expandafteredefcsnameflag trueendcsname{ oexpandletcsname ifflagendcsname= oexpandiftrue}

            試一試,

            * showabctrue> abctrue=macro:->let ifabc =iftrue

            和 ③ 處一摸一樣,OK!

            綜上, ewif 的最終實現為,

            def ewif#1{ edefflag{unwrap #1} edefflag{expandafter ailflag} edefflag{expandafter ailflag} expandafteredefcsnameflag trueendcsname{ oexpandletcsname ifflagendcsname= oexpandiftrue} expandafteredefcsnameflag falendcsname{ oexpandletcsname ifflagendcsname= oexpandiffal} abcfal}

            試一試,

            ewififabcifabc abc true el abc fal % => abc falfiabctrueifabc abc true % => abc trueel abc falfi

            OK!

            這詞法宏看著不難,但是用起來很容易出來,大家使用時一定要謹慎。

            在任何語言的使用的討論中,數據結構都是不可避免的話題,而列表又是數據結構的核心之一。前面討論過 逗號分隔 的 整數列,這里在我們談談 TeX 代碼本身,即,標記列,標記列寄存器本來就是用來保存它的,它才是 TeX 的第一等公民,接下來,如果無特殊說明,所謂 列表 就是指它。

            借助于前面討論過的 edef + he 的特性,很容易將兩個 標記列寄存器 合并起來,放在一個列表宏里,

            edefc{ he oks0 he oks1}

            于是要合并兩個列表宏,只需要在這之前,將其內容保存在 這兩個標記列寄存器中,

            oks0=expandafter{a} oks0=expandafter{}

            其中 expandafter 確保 a 被展開,而非以 命令的 形式 呆在 列表中。在這里標記列寄存器僅僅是臨時被使用,我們的列表最終都保持在宏中。

            將以上代碼封裝起來就是,

            defconcat#1=#2{ oks0=expandafter{#2} oks1=expandafter{#3} edef#1{ he oks0 he oks1}}

            測試一下,

            edefa{a} edef{b}concatc=a& c % => ab

            OK!

            接著就是列表中往添加元素問題。之前的整數列 的元素 之間 是用 逗號分隔的,即,

            n1, n2, n3

            而這次的是標記列,每個元素item都是(一個或多個)標記,所以應該用 分組來分隔,然后為了將來通過宏參數的模式匹配來處理列表,還需要在每個分組前面再加上@用來定界,因此我們的列表元素是這樣的,

            @{item1}@{item2}@{item3}

            這樣以來,在列表末尾 添加元素的具體代碼如下,

            defappend#1 o#2{ oks0={@{#1}} oks1=expandafter{#2} edef#2{ he oks1 he oks0}}

            測試測試,

            letlst=emptyappend a olst append b olst append c olst showlst % -> @{a}@{b}@{c}.

            OK! 當然,也允許向列表頭添加元素,代碼如下,

            defunshift#1 o#2{ oks0={@@{#1}} oks1=expandafter{#2} edef#2{ he oks0 he oks1}}

            測試一下,

            unshift 0 olstshowlst % -> @{0}@{a}@{b}@{c}.

            OK!

            然后,就是取出列表的首項了,代碼如下,

            defshift#1 o#2{ defperformshift@##1##2 o##3##4{def##3{##1} def##4{##2}} expandafterperformshift#1 o#2#1}

            試一試,

            shift lst oshow % -> 0.showlst % ->@{a}@{b}@{c}.

            OK!

            最后,就是對列表中元素的處理問題了。在之前的整數列中,我們使用了函數式語言的傳統方法,即,

            把整數列中的每個元素取出來進行處理,然后再將處理結果組成新的整數列 ;

            但這里的 標記列,其實就是 TeX 代碼,它本身就可以運行的,如果我們用 而我們特意使用了 宏命令 @ 作為 分界符,它索然在參數匹配中不起作用,但是如果 列表去運行,就會被執行,不就相當于獲得了 處理 對每個 元素的能力嗎?

            按照這個思路,我們只需要,將處理動作提前封裝在 @, 然后讓列表宏 執行,就可以了處理列表元素了。例如,計算列表的長度,

            deflength#1 o#2{ #2=0 def@##1{advance #2 by 1} #1}

            測試一下,

            showlst % ->@{a}@{b}@{c}.lengthlst oeax % => 空showtheeax % -> 3.

            完美!

            將列表輸出成我們熟悉的寫法非常容易,

            def helist#1{ eax=0 def@##1{ advance eax by 1 ifnum eax=1 el , fi ##1} #1} helistlst % => a,b,c

            OK!

            實現map功能同樣非常容易,

            defmap#1y#2 o#3{ let#3=empty def@##1{ edefmaptemp{#2##1} expandafterappend maptemp o#3} #1}

            測試一下,

            defuc#1{ if a#1 A el if b#1 B el if c#1 C el ... fififi}maplstyuc oashowa % ->@{ A }@{ B }@{ C }.

            OK!

            注意:由于這個map的實現是,在 定義時 調用 #2 的,所以 #2 中的實現不能使用 非運行時 的原子命令,比如 advance 等。

            (好了,續三就寫到這里吧!關于 TeX編程的更多內容,后續文章再討論!)

            本文發布于:2023-02-28 21:21:00,感謝您對本站的認可!

            本文鏈接:http://www.newhan.cn/zhishi/a/1677750251110964.html

            版權聲明:本站內容均來自互聯網,僅供演示用,請勿用于商業和其他非法用途。如果侵犯了您的權益請與我們聯系,我們將在24小時內刪除。

            本文word下載地址:個性分組符號(個性分組符號怎么打).doc

            本文 PDF 下載地址:個性分組符號(個性分組符號怎么打).pdf

            標簽:符號   個性
            相關文章
            留言與評論(共有 0 條評論)
               
            驗證碼:
            Copyright ?2019-2022 Comsenz Inc.Powered by ? 實用文體寫作網旗下知識大全大全欄目是一個全百科類寶庫! 優秀范文|法律文書|專利查詢|
            主站蜘蛛池模板: 国产白袜脚足j棉袜在线观看| 久章草这里只有精品| 91精品国产午夜福利| 爱如潮水在线观看视频| 久久亚洲精品天天综合网| 亚洲欧洲精品国产二码 | 色噜噜一区二区三区| 韩国三级在线 中文字幕 无码| 老熟妇仑乱视频一区二区| 无套内谢少妇一二三四| 国产亚洲曝欧美精品手机在线| 91老熟女老人国产老太| 综合色在线| 亚洲精品日韩中文字幕| 国产WW久久久久久久久久| 久久婷婷国产精品香蕉| 国语自产精品视频在线看| 无码熟熟妇丰满人妻porn | 亚洲人黑人一区二区三区| 午夜福利看片在线观看| 国产又黄又爽又不遮挡视频| 国产国产久热这里只有精品| 日韩av片无码一区二区不卡| 日韩有码中文字幕第一页| 国产95在线 | 欧美| 国产精品va在线观看h| 亚洲国产成人字幕久久| 他掀开裙子把舌头伸进去添视频| 精品一区二区三区在线视频观看| 99re热精品视频中文字幕不卡 | 人妻日韩人妻中文字幕| 中文字幕精品亚洲四区| 国产成人无码区免费内射一片色欲| 天堂中文8资源在线8| 中文乱码字幕在线中文乱码| 内射老阿姨1区2区3区4区| 亚洲一区二区三区影院| 国产成人综合亚洲欧美日韩| 午夜精品福利亚洲国产| 成熟少妇XXXXX高清视频| 欧美成人精品 一区二区三区|