让CellDingbat记住Mathematica会话之间的状态

JxB*_*JxB 8 wolfram-mathematica stylesheet

我修改了我的笔记本的样式表,以包含一个StyleData["Todo"]继承自的样式表StyleData["Item"].它将单元格dingbat更改为复选框.在样式表编辑器中:

Cell[StyleData["ToDo", StyleDefinitions -> StyleData["Item"]], 
  CellDingbat->DynamicModuleBox[{$CellContext`color$$}, 
    CheckboxBox[
    Dynamic[$CellContext`color$$], {RGBColor[1, 0.5, 0],RGBColor[0,Rational[2, 3], 0]},    
    Background -> Dynamic[$CellContext`color$$]], 
    DynamicModuleValues :> {}
  ],
]
Run Code Online (Sandbox Code Playgroud)

问题是,当在笔记本中使用时,复选框的状态不会保存在Mathematica会话之间.我以为DynamicModule[]会做到这一点.如何让复选框记住其状态?

编辑

Simon的解决方案确实保存了复选框的状态,但是当用作CellDingbat(MacOS X)时,复选框会被剪切.将Simon的代码放在CellFrameLabels选项中可以解决问题,并保留默认的"Item"CellDingbat.这就是我的用处:

Cell[StyleData["ToDo", StyleDefinitions -> StyleData["Item"]],
 CellFrameLabels->{{
    ButtonBox[
     CheckboxBox[False], ButtonFunction :> (SelectionMove[
        ButtonNotebook[], All, ButtonCell]; 
      With[{$CellContext`new = ReplaceAll[
           Options[
            NotebookSelection[
             ButtonNotebook[]], CellFrameLabels], CheckboxBox[
             Pattern[$CellContext`x, 
              Alternatives[True, False]]] :> CheckboxBox[
             Not[$CellContext`x]]]}, 
        SetOptions[
         NotebookSelection[
          ButtonNotebook[]], $CellContext`new]]; SelectionMove[
        ButtonNotebook[], After, CellContents]), Appearance -> None, 
     Method -> "Preemptive", Evaluator -> Automatic], None}, {
   None, None}},
 MenuSortingValue->1621]
Run Code Online (Sandbox Code Playgroud)

Sim*_*mon 3

您的代码的问题(我认为)是DynamicModule每次创建新的“ToDo”单元时都不会创建新的单元。所以没有地方Checkbox可以保存每个人的状态。

我能想到的存储每个“ToDo”单元格状态的最简单的解决方案是在第一次激活时Checkbox覆盖。(我使用的其他选项是使用,在“ToDo”和“ToDone”样式之间切换,等等......)CellDingbatCheckboxTaggingRules

Checkbox但是,即使a 中的普通数据也不会存储其状态 - 尝试运行以下命令,然后通过“显示表达式”循环CellDingbat循环输出。

CellPrint[Cell["test", "Text", CellDingbat -> ToBoxes[Checkbox[]]]]
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我使用了Checkbox明确的参数TrueFalse包裹在一个改变状态的按钮中。这是愚蠢且低效的,但它确实有效!

所以,我的单元格样式代码

Cell[StyleData["ToDo", StyleDefinitions -> StyleData["Item"]],
 CellDingbat -> ButtonBox[CheckboxBox[False], 
   ButtonFunction :> (SelectionMove[ButtonNotebook[], All, ButtonCell]; 
     With[{$CellContext`new = ReplaceAll[
          Options[NotebookSelection[ButtonNotebook[]], CellDingbat], 
          CheckboxBox[Pattern[$CellContext`x, Alternatives[True, False]]] :> CheckboxBox[Not[$CellContext`x]]]}, 
        SetOptions[NotebookSelection[ButtonNotebook[]], $CellContext`new]]; 
      SelectionMove[ButtonNotebook[], After, CellContents]), 
    Appearance -> None, Method -> "Preemptive", Evaluator -> Automatic]]
Run Code Online (Sandbox Code Playgroud)

截图

我对这个解决方案并不满意,但这是我想出的最好的解决方案。一项改进是将按钮功能代码移出单元格,这样就不会为每个选中的待办事项单元格重复该代码。还可以使其在没有 a 的情况下运行ReplaceAll,这样就不需要内核,并且该函数可以仅使用前端来运行。