13
$\begingroup$

The example cells in the documentation each have a count of the cells inside their section:

 Cell[TextData[{"Basic Examples", "  ", Cell["(4)", "ExampleCount"]}],
   "ExampleSection", "ExampleSection"]

But this is static content, how exactly would this work dynamically? I'd like to make my own cell style where the cell dingbat counts the number of cells inside the cell group it contains (and updates itself dynamically of course).

I've looked at the stylesheet for outline-styled notebooks and then tried using the Counter* options, but these are for dynamic tallying, not content counting and there's not much documentation on these esoteric front-end things like

CounterBoxOptions->{CounterFunction:>CapitalRomanNumeral}]

Any help would be appreciated.

enter image description here

$\endgroup$
  • $\begingroup$ Maybe you can setup a Notebook-level Dynamic object doing the counting, and just refer to its result at any place you want. (With the help of CellID/CellTags/etc. maybe.) $\endgroup$ – Silvia Feb 6 '15 at 13:53
  • $\begingroup$ @Silvia Good idea, but I foresee a problem: If a Dynamic expression is not visible in the notebook's window (i.e. scrolled out of range) we are out of luck... And having that Dynamic always running impact performance? $\endgroup$ – M.R. Feb 6 '15 at 16:17
  • 1
    $\begingroup$ That is why I think a Notebook-level Dynamic object (such as NotebookEventActions, NotebookDynamicExpression or similar) should be used, so as long as the nb is visible, the counter will work. About the performance, I'm sorry but I really can't come up with a way without Dynamic.. $\endgroup$ – Silvia Feb 7 '15 at 3:18
  • $\begingroup$ I don't think you can do this with standard Counters since you would have to know the counter state before cells that are going to increment it. And it seems the notebook is read by the FE in one direction. $\endgroup$ – Kuba Nov 15 '15 at 14:30
8
$\begingroup$

I think when it's done each time you save the notebook it should be nice enough :)

SetOptions[
 EvaluationNotebook[],
 NotebookEventActions -> {
   {"MenuCommand", "Save"} :> (Scan[
      Module[{nr},
        SelectionMove[#, All, CellGroup, AutoScroll -> False];
        nr = Length @ Select[
           SelectedCells[], 
           Experimental`CellStyleNames[#] === "Input" & (*1*)
        ];
        SetOptions[#, CellDingbat -> "(" <> ToString[nr] <> ")"];
      ] &
      ,
      Cells[CellStyle -> "Section"] (*2*)
   ]),
   PassEventsDown -> True
   }
 ]

Ad 1. Cell style to count

Ad 2. Cell style whose parent group end "resets the counter"

You can use it in stylesheets too.

enter image description here


Update from Question's Author:

As Kuba's comment fixes the raggedness:

SetOptions[EvaluationNotebook[], 
     NotebookEventActions -> {{"MenuCommand", 
         "Save"} :> (Scan[
          Module[{nr}, 
            SelectionMove[#, All, CellGroup, AutoScroll -> False];

            nr = Length@
              Select[SelectedCells[], 
               Experimental`CellStyleNames[#] === 
                 "ItemNumbered" & (*1*)];

            SetOptions[#, 
             CellDingbat -> 
              Cell[BoxData[
                PaneBox[
                 StyleBox[ToString[nr] <> "   ", 
                  RGBColor[0.5, 0.5, 0.67, 0.81], 
                  FontFamily -> "Continuum Light", 15], 
                 Alignment -> Right, ImageSize -> 40]], 
               Background -> White]];] &, 
          Cells[CellStyle -> "Subsection"] (*2*)]), 
       PassEventsDown -> True}]

enter image description here

$\endgroup$
  • $\begingroup$ This isn't a stylesheet though $\endgroup$ – M.R. Nov 19 '15 at 14:53
  • $\begingroup$ @M.R. I must admit I have not tried but I though it should work as an option to StyleData[Notebook] Cell $\endgroup$ – Kuba Nov 19 '15 at 14:56
  • $\begingroup$ Also it induces unwanted indentations. Maybe we could have a quick chat session $\endgroup$ – M.R. Nov 19 '15 at 15:26
  • $\begingroup$ @M.R. I will try to address your questions later, I have to go offine atm. Do you want to include (5) after the cell content? $\endgroup$ – Kuba Nov 19 '15 at 15:30
  • $\begingroup$ No its just that when the number varies in digit length, the left margins of section cells are all different and look ragged. $\endgroup$ – M.R. Nov 19 '15 at 15:34
1
$\begingroup$

Here is a stylesheet solution that gives "Section" cells a dingbat that counts the number of "Input" cells in the section:

SetOptions[
    EvaluationNotebook[],
    StyleDefinitions -> Notebook[
        {
        Cell[StyleData[StyleDefinitions -> "Default.nb"]], 
        Cell[StyleData["Input"],
            CounterIncrements -> "CellCount"
        ],
        Cell[StyleData["Notebook"],
            TaggingRules -> "TotalCells" -> Dynamic[Length[Cells[CellStyle -> "Input"]]]
        ],
        Cell[StyleData["Section"], 
            CellDingbat -> Cell @ BoxData @ DynamicBox[
                RowBox[{
                    "(",
                    ToBoxes[
                        AbsoluteCurrentValue[ParentCell[EvaluationCell[]], {TaggingRules, "NextSection"}] - 
                        AbsoluteCurrentValue[ParentCell[EvaluationCell[]], {TaggingRules, "ThisSection"}]
                    ],
                    ")"
                }]
            ], 
            TaggingRules -> {
                "NextSection" -> Dynamic @ Replace[
                    NextCell[CellStyle -> "Section"], 
                    {
                    None :> CurrentValue[EvaluationNotebook[], {TaggingRules, "TotalCells"}], 
                    o_ :> CurrentValue[o, {"CounterValue", "CellCount"}]
                    }
                ],
                "ThisSection" -> Dynamic[CurrentValue[EvaluationCell[], {"CounterValue", "CellCount"}]]}], 
        }, 
        StyleDefinitions -> "PrivateStylesheetFormatting.nb"
    ]
]

Note that all the dynamic content might cause the notebook to be laggy.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.