ConversionRules and style inheritance

5

3

Take the LaTeX-Article stylesheet

stylesheet = FileNameJoin[{"Article","LaTeX-Article.nb"}];

Compare these outputs

ExportString[
 Notebook[{Cell["Numbered?", "Section"]}, StyleDefinitions -> stylesheet],
 "TeXFragment"]

(* \section{Numbered?} *)

ExportString[
 Notebook[{Cell["Numbered?", "Section"]}, 
  StyleDefinitions -> 
   Notebook[{Cell[StyleData[StyleDefinitions -> stylesheet]]}]],
 "TeXFragment"]

(* \section*{Numbered?} *)

Do you all see this difference? What's the reason for it?

Rojo

Posted 2014-12-23T17:10:04.440

Reputation: 40 993

1Éramos pocos... Where have you been? – Dr. belisarius – 2014-12-23T17:15:38.980

@belisarius :) around in the end-of-year rush – Rojo – 2014-12-23T17:43:31.490

Shaná Tová, then for you and all your dearlings – Dr. belisarius – 2014-12-23T17:59:50.817

@belisarius Thanks, Shaná Tová to you too! – Rojo – 2014-12-23T19:39:10.327

Answers

5

Why inherited conversion rules are not used

In complicated process of exporting, at some stage, System`Convert`CommonDump`ConvertNotebook function is called. If you look at its source, you'll see that it extracts style definitions from notebook and from $FrontEnd. Then, for style definitions that are strings or FrontEnd`FileName expressions, it gets explicit notebook expressions using System`Convert`CommonDump`GetStyleSheet function. Stylesheet notebooks are then passed to System`Convert`CommonDump`StyleSheetsToMarkupRules function, to extract conversion rules.

StyleSheetsToMarkupRules function starts by calling System`Convert`CommonDump`ExtractStyleDataCells, which extracts cells matching Cell[StyleData[_String, ___], ___] pattern and ignores all other cells. That's why inherited stylesheets, i.e. ones present in Cell[StyleData[StyleDefinitions -> ...]] cells, are not used in conversion.

Starred section command, in your second example, comes from default rules stored in:

System`Convert`CommonDump`DefaultMarkupRules[System`Convert`TeXDump`texsave]

How to fix conversion rules inheritance

Unfortunatly I don't know a way of fixing this without changing behavior of builtin function.

If you don't mind a small hack, you can start with function that takes all style inheritance cells, pointing to filenames and put them at the and of stylesheet notebook, with referenced filenames replaced by explicit notebook expressions.

We need to move inherited styles to the end of notebook, so that definitions from inheriting stylesheet will properly override inherited definitions.

ClearAll[styleFilenamePatt, styleInheritanceCell, explicitInheritedStylesheets];

styleFilenamePatt = Except["Core.nb", _String | _System`Convert`CommonDump`fnpatt];
styleInheritanceCell = Cell[StyleData[StyleDefinitions -> styleFilenamePatt]];

explicitInheritedStylesheets[styleSheets_] := styleSheets //. Notebook[cells_, opts___] :> 
    Notebook[
        Join[
            DeleteCases[cells, styleInheritanceCell, Infinity]
            , 
            Cases[cells,
                Cell[StyleData[StyleDefinitions -> filename : styleFilenamePatt]] :>
                    Cell[StyleData[
                        StyleDefinitions -> System`Convert`CommonDump`GetStyleSheet[filename]
                    ]]
                ,
                Infinity
            ]
        ]
        ,
        opts
    ]

Inject explicitInheritedStylesheets function to StyleSheetsToMarkupRules using Villegas-Gayley:

Module[{inside},
    System`Convert`CommonDump`StyleSheetsToMarkupRules[
        styleSheets_, markupLanguage_, environment_: None
    ] /; ! TrueQ[inside] :=
        Block[{inside = True},
            System`Convert`CommonDump`StyleSheetsToMarkupRules[
                styleSheets // explicitInheritedStylesheets,
                markupLanguage,
                environment
            ]
        ]
]

Now conversion rules from inherited stylesheets should work as expected:

ExportString[
    Notebook[{Cell["Numbered?", "Section"]}, StyleDefinitions -> stylesheet],
    "TeXFragment"
]
(* \section{Numbered?} *)

ExportString[
    Notebook[
        {Cell["Numbered?", "Section"]},
        StyleDefinitions -> Notebook[{Cell[StyleData[StyleDefinitions -> stylesheet]]}]
    ],
    "TeXFragment"
]
(* \section{Numbered?} *)

jkuczm

Posted 2014-12-23T17:10:04.440

Reputation: 14 388