在 ConTeXt 中自定义定理环境

在 ConTeXt 中自定义定理环境

我看过一篇帖子(编辑定理环境) 解释如何theorem使用包在 LaTeX 中自定义环境thmbox

原来的

我希望我的文档有相同的输出,但我只使用 ConTeXt,而且我不是 TeX 专家。有人能告诉我如何从头开始或使用 ConTeXt 机制来实现这一点吗?此外,我更希望:

  • 规则更厚
  • 角是圆的
  • 底部规则横跨整个页面
  • 环境可以跨页面分割

像这样 :

修改的

提前致谢!

答案1

这是另一种解决方案。让我们先从不跨页中断的版本开​​始。我们稍后会修复该问题。

首先,让我们尝试获得没有框架的基本布局。与其他解决方案不同,我没有将定理头移到右侧,而是将定理主体移到左侧。

\defineenumeration[THEOREMenumeration]
                  [
                    text=Theorem ,%Space after Theorem is delibrate
                    title=yes,
                    alternative=hanging, 
                    titlestyle=boldslanted, % or bolditalic
                    style=slanted, % or italic
                    width=fit,
                 ]


\define\starttheorem
  {\dosingleargument\dostarttheorem}

\def\dostarttheorem[#1]%
    {\startTHEOREMenumeration[#1]%
     \crlf
     }

\define\stoptheorem
    {\stopTHEOREMenumeration
    }


\starttext
\input ward
\starttheorem[title={Riemann-Lebesgue}]
  \input ward
  Pour tout $f \in L^1({\Bbb T})$, on a
  \startformula
    \lim_{|n| \to ∞} c_n(f) = 0
  \stopformula
\stoptheorem

\input knuth
\stoptext

这使:

在此处输入图片描述

现在我们需要的只是框架。要获得定理头部周围的底线规则,可以使用:

\defineenumeration[THEOREMenumeration]
                  [
                    ....
                    headcommand=\THEOREMframed,
                 ]

其中\THEOREMframed定义为:

  \defineframed     [THEOREMframed]
                    [
                      frame=off,
                      bottomframe=on,
                      location=low,
                      rulethickness=2bp,
                    ]

这使:

在此处输入图片描述

该规则与下一行重叠,但我们稍后会修复它。

现在,为了获得定理主体的框架,将\starttheorem和的定义更改\stoptheorem为:

\def\dostarttheorem[#1]%
    {\startTHEOREMenumeration[#1]%
     \startTHEOREMframedtext
     }

\define\stoptheorem
    {\stopTHEOREMframedtext
     \stopTHEOREMenumeration
    }

其中THEOREMframedtext定义为:

\defineframedtext [THEOREMframedtext]
                  [
                    offset=0pt,
                    loffset=1em,
                    boffset=1em,
                    corner=15,
                    width=broad,
                    rulethickness=2bp,
                    before=,
                    after=,
                    strut=no,
                  ]

这使:

在此处输入图片描述

请注意,该定理现在太宽泛了。我们可以通过使用以下方法解决这个问题:

\defineframedtext [THEOREMframedtext]
                  [ 
                  ....
                    width=\dimexpr(\hsize-\framedparameter{loffset} -\framedparameter{rulethickness})\relax,
                  ....
                  ]

完整代码如下:

\defineenumeration[THEOREMenumeration]
                  [
                    text=Theorem ,%Space after Theorem is delibrate
                    title=yes,
                    alternative=hanging, 
                    titlestyle=boldslanted, % or bolditalic
                    style=slanted, % or italic
                    width=fit,
                    headcommand=\THEOREMframed,
                 ]

  \defineframed     [THEOREMframed]
                    [
                      frame=off,
                      bottomframe=on,
                      location=low,
                      rulethickness=2bp,
                    ]

\defineframedtext [THEOREMframedtext]
                  [
                    offset=0pt,
                    loffset=1em,
                    boffset=1em,
                    corner=15,
                    width=\dimexpr(\hsize-\framedparameter{loffset} -\framedparameter{rulethickness})\relax,
                    rulethickness=2bp,
                    before=,
                    after=,
                    strut=no,
                  ]



\define\starttheorem
  {\dosingleargument\dostarttheorem}

\def\dostarttheorem[#1]%
    {\startTHEOREMenumeration[#1]%
     \startTHEOREMframedtext
     }

\define\stoptheorem
    {\stopTHEOREMframedtext
     \stopTHEOREMenumeration
    }


\starttext
\input ward
\starttheorem[title={Riemann-Lebesgue}]
  \input ward
  Pour tout $f \in L^1({\Bbb T})$, on a
  \startformula
    \lim_{|n| \to ∞} c_n(f) = 0
  \stopformula
\stoptheorem

\input knuth
\stoptext

现在,为了确保正文可以跨页面拆分,我们需要将 更改为framedtexttextbackground的键textbackgroud与 的键不同framedtext。我们从以下开始:

\definetextbackground [THEOREMframedtext]
                  [
                    mp=ellframe,
                    location=paragraph,
                    leftoffset=1em,
                    topoffset=1.5ex,
                    bottomoffset=1em,
                    rightoffset=0pt,
                    rulethickness=2bp,
                    framecolor=black,
                    before=,
                    after=,
                    strut=no,
                  ]

在此处输入图片描述

现在我们需要做的就是定义ellframe绘制 L 形框架的 metapost 图形。在此之前,我们需要确定当定理溢出页面时会发生什么:我们应该在两页上都绘制 L 形框架,还是应该在第一页上绘制一条直线,在第二页上绘制一条 L 形框架?如果定理跨越三页这种不太可能的情况发生,会发生什么?ConTeXt 可以轻松编写针对每种情况的专用代码。

\startuseMPgraphic{ellframe}
  begingroup;
    interim linecap := butt ;
    for i=1 upto nofmultipars :
      if multikind[i] = "single" :
          draw ( ulcorner multipars[i] -- 
               ( llcorner multipars[i] + (0, boxlineradius )){down} ..
               {right}(llcorner multipars[i] + (boxlineradius, 0) ) --
                 lrcorner multipars[i] )
      elseif multikind[i] = "first" :
          draw leftboundary   multipars[i] 
      elseif multikind[i]= "middle" :
          draw leftboundary  multipars[i] 
      elseif multikind[i]= "last" :
          draw ( ulcorner multipars[i] -- 
               ( llcorner multipars[i] + (0, boxlineradius )){down} ..
               {right}(llcorner multipars[i] + (boxlineradius, 0) ) --
                 lrcorner multipars[i] )
      fi 
      boxlineoptions withpen pencircle scaled boxlinewidth ;
    endfor ;
  endgroup;
\stopuseMPgraphic

这是没有分页符时的输出:

在此处输入图片描述

当定理跨页时,输出结果如下:

在此处输入图片描述

最终的完整代码如下:

\defineenumeration[THEOREMenumeration]
                  [
                    text=Theorem ,%Space after Theorem is delibrate
                    title=yes,
                    alternative=hanging, 
                    titlestyle=boldslanted, % or bolditalic
                    style=slanted, % or italic
                    width=fit,
                    headcommand=\THEOREMframed,
                 ]

\defineframed     [THEOREMframed]
                  [
                    frame=off,
                    bottomframe=on,
                    location=low,
                    rulethickness=2bp,
                  ]

\definetextbackground [THEOREMframedtext]
                  [
                    mp=ellframe,
                    location=paragraph,
                    leftoffset=1em,
                    topoffset=1.5ex,
                    bottomoffset=1em,
                    rightoffset=0pt,
                    rulethickness=2bp,
                    framecolor=black,
                    before=,
                    after=,
                    strut=no,
                  ]

\startuseMPgraphic{ellframe}
  begingroup;
    interim linecap := butt ;
    for i=1 upto nofmultipars :
      if multikind[i] = "single" :
          draw ( ulcorner multipars[i] -- 
               ( llcorner multipars[i] + (0, boxlineradius )){down} ..
               {right}(llcorner multipars[i] + (boxlineradius, 0) ) --
                 lrcorner multipars[i] )
      elseif multikind[i] = "first" :
          draw leftboundary   multipars[i] 
      elseif multikind[i]= "middle" :
          draw leftboundary  multipars[i] 
      elseif multikind[i]= "last" :
          draw ( ulcorner multipars[i] -- 
               ( llcorner multipars[i] + (0, boxlineradius )){down} ..
               {right}(llcorner multipars[i] + (boxlineradius, 0) ) --
                 lrcorner multipars[i] )
      fi 
      boxlineoptions withpen pencircle scaled boxlinewidth ;
    endfor ;
  endgroup;
\stopuseMPgraphic

\define\starttheorem
  {\dosingleargument\dostarttheorem}

\def\dostarttheorem[#1]%
    {\startTHEOREMenumeration[#1]%
     \page[no]
     \startTHEOREMframedtext
     }

\define\stoptheorem
    {\stopTHEOREMframedtext
     \stopTHEOREMenumeration
    }

答案2

受到 Metafun 手册的启发(搜索 FunnyFrame)和此主题在 ConTeXt 列表中。它满足了您的一些查询,但它不会拆分页面。我不知道该怎么做。而且,它相当手动。可能有更好的方法来做这种事情,所以把它看作一个开始。

\definenumber[ThmNumber][way=bychapter, prefix=no]
\setnumber[ThmNumber][1]


\startuseMPgraphic{FunnyFrame}
picture p ; numeric w, h, o ; path f;
p := textext.rt(\MPstring{ThmTitle}) ;
w := OverlayWidth ; h := OverlayHeight ; o := BodyFontSize ;
p := p shifted (-o,h) ; draw p ;
drawoptions (withpen pencircle scaled 1pt) ;


pair pf;
pf := lrcorner p;
draw lrcorner p -- llcorner p ;
f := (0,ypart pf) -- (0,1mm){down}..{right}(1mm,0)--(w-o,0);
draw f;
setbounds currentpicture to unitsquare xyscaled(w,h) ;
\stopuseMPgraphic


\defineoverlay[FunnyFrame][\useMPgraphic{FunnyFrame}]


\defineframedtext[Thm]
[frame=off,
style=\it,
background=FunnyFrame,
offset=\bodyfontsize,
width=\dimexpr(\textwidth+\bodyfontsize),
before={\blank[line]},
after={\incrementnumber[ThmNumber]\blank}]

\define[2]\FrameTitle%
{\setMPtext{ThmTitle}{\hbox{\hss\strut\bf #1 \namedheadnumber{chapter}.\getnumber[ThmNumber] {\em #2}\hss}}}

\starttext

\chapter{Test chapter}
\setnumber[ThmNumber][1]

\FrameTitle{Theorem}{(Pythagoras)}
\startThm
It holds that
\startformula
a^2+b^2=c^2.
\stopformula
\stopThm
\input Zapf
\FrameTitle{Lemma}{}
\startThm
If $a>b$ and $c>0$ then $ac>bc$. \input tufte\par
\stopThm

在此处输入图片描述

答案3

这是一个简单的解决方案,但仅与问题类似。我使用描述和框架。

    \defineframedtext[styletheoreme]
                     [frame=on,%
                      rulethickness=1mm,%
                      strut=no,%
                      width=0.6\paperwidth,%
                      location=middle,%
                      corner=15,% 
                      toffset=-8mm,% 
                     ]
    \defineframed[titretheoreme]
                     [frame=off,%
                      bottomframe=on,
                      rulethickness=1mm,%
                      width=fit,%
                      location=top,%
                      toffset=-5mm,%
                     ]
    \definedescription[theoreme][width=fit,%
                                 alternative=top,%
                                 headcommand={\hskip -10mm \titretheoreme},%     
                                 before={\startstyletheoreme},%
                                 after={\stopstyletheoreme}%                    
                                  ]


    \starttext
    \starttheoreme{Un théorème}

    Blabla
    \startformula
    \sum_{k=1}^n k = \frac{n(n+1)}2
    \stopformula
    \stoptheoreme
\stoptext

corner=15 记录在http://wiki.contextgarden.net/Framed#Rounded_Corners toffset=-8mm 允许降低框架

您必须调整尺寸。

它不会分割页面。

在此处输入图片描述

相关内容