This code is far from being complete, but since I promised to show something
this weekend, I decided to publish it anyway.

It provides functions for converting *Mathematica* cells to TeX code
compatible with [mmacells](https://github.com/jkuczm/mmacells) package.
 
 Import["https://raw.githubusercontent.com/jkuczm/MathematicaOptionsUtilities/master/OptionsUtilities/OptionsUtilities.m"]
 
 
 ClearAll[ruleToMakeStringDef]
 
 ruleToMakeStringDef::usage = "\
 ruleToMakeStringDef[lhs -> rhs] or ruleToMakeStringDef[lhs :> rhs] \
 assigns definitions to makeString function using given rule."
 
 ruleToMakeStringDef[lhs_ -> rhs_] := (makeString[lhs] = rhs)
 ruleToMakeStringDef[lhs_ :> rhs_] := (makeString[lhs] := rhs)
 
 
 ClearAll[makeStringDefault]
 
 makeStringDefault::usage = "\
 makeStringDefault[boxes] \
 returns String representation of given boxes. \
 This function is called by makeString function, when no user provided BoxRule \
 applies."
 
 makeStringDefault[boxes_List] := StringJoin[makeString /@ boxes]
 makeStringDefault[BoxData[boxes_]] := makeString[boxes]
 
 
 ClearAll[makeString]
 
 makeString::usage = "\
 makeString[boxes] \
 returns String representation of given boxes. \
 Definitions for this function are locally created from user provided BoxRules \
 on each evaluation of boxesToString function."
 
 makeString[arg_] := makeStringDefault[arg]
 
 
 ClearAll[boxesToString]
 
 boxesToString::usage = "\
 boxesToString[boxes] \
 returns String representation of given boxes."
 
 boxesToString::unspt = "FormatType: `1` is not supported."
 
 Options[boxesToString] = Append[Options[ToString], "BoxRules" -> {}]
 boxesToString[boxes_, opts : OptionsPattern[]] :=
 Internal`InheritedBlock[{makeStringDefault, makeString, ToString},
 Switch[OptionValue[FormatType],
 InputForm,
 makeStringDefault[RowBox[l_List]] := makeString[l];
 makeStringDefault[str_String] := str;
 makeStringDefault[arg_] := ToString[arg],
 OutputForm,
 makeStringDefault[RowBox[l_List]] := 
 ToString[DisplayForm[RowBox[makeString /@ l]]];
 makeStringDefault[str_String] := 
 ToString[DisplayForm[RowBox[{str}]]];
 makeStringDefault[arg_] := ToString[DisplayForm[arg]],
 _,
 Message[boxesToString::unspt, OptionValue[FormatType]];
 Return[$Failed]
 ];
 ruleToMakeStringDef /@ OptionValue["BoxRules"];
 SetOptions[ToString, DelegateOptions[opts, boxesToString, ToString]];
 makeString[boxes]
 ]
 
 
 ClearAll[boxRulesToBoxPattern]
 
 boxRulesToBoxPattern::usage = "\
 boxRulesToBoxPattern[{boxPatt1 -> result1, boxPatt2 :> result2, ...}] \
 returns pattern that matches any of boxPatti."
 
 boxRulesToBoxPattern[boxRules_] := 
 Alternatives @@ boxRules[[All, 1]] /. Verbatim[Pattern][_, patt_] :> patt
 
 
 ClearAll[boxesOfTypeQ]
 
 boxesOfTypeQ::usage = "\
 boxesOfTypeQ[boxes, type] \
 returns True if given boxes contain only subboxes mathcing given pattern \
 type. Returns False otherwise."
 
 boxesOfTypeQ[boxes_, type_] := FreeQ[boxes, Except[type], Heads -> False]
 
 
 ClearAll[$commandChars];
 
 $commandChars::usage = "\
 $commandChars \
 is a List of three rules. With left hand sides being: eascape character and \
 argument delimiters used by TeX formatting commands. Right hand sides are \
 strings used to represent escaped commandChars."
 
 $commandChars = {"\\" -> "\\textbackslash{}", "{" -> "\\{", "}" -> "\\}"}
 
 
 ClearAll[headRuleToBoxRule]
 
 headRuleToBoxRule::usage = "\
 headRuleToBoxRule[boxHead -> commandName] \
 returns rule that transforms box with given head to TeX formatting command \
 with given name."
 
 headRuleToBoxRule[boxHead_ -> command_String] := 
 boxHead[boxes___] :>
 $commandChars[[1, 1]] <> command <> (
 $commandChars[[2, 1]] <> makeString[#] <> $commandChars[[3, 1]]& /@
 {boxes}
 )
 
 
 (* Dummy evaluation to laod System`Convert`TeXFormDump` context. *)
 Convert`TeX`BoxesToTeX
 
 ClearAll[characterToTeXVerbatimCode]
 
 characterToTeXVerbatimCode::usage = "\
 characterToTeXVerbatimCode[\"x\"] \
 returns String with TeX code, representing given character, suitable for \
 inclusion in Verbatim environment."
 
 characterToTeXVerbatimCode[char_] :=
 StringReplace[
 StringJoin @ Replace[
 System`Convert`TeXFormDump`TextExceptions @
 System`Convert`TeXFormDump`TeXCharacters[char]
 ,
 {"$", texStr_, "$"} :>
 If[StringFreeQ[texStr, "\\"],
 texStr
 (* else *),
 {"\(", texStr, "\)"}
 ]
 ]
 ,
 " " -> ""
 ]
 
 
 ClearAll[
 $currentValueObj, $basicBoxes, $verbatimCodeBoxRulesLinear,
 $verbatimCodeBoxHeadRulesFormatted, $verbatimCodeSubStringRulesFormatted,
 $verbatimCodeBoxRulesFormatted
 ]
 
 $currentValueObj::usage = "\
 $currentValueObj \
 is a notebook or front end object used as basis for CurrentValue evaluations \
 extracting styles needed for conversion of some boxes."
 $currentValueObj = Sequence[]
 
 $basicBoxes::usage = "\
 $basicBoxes \
 is a pattern matching basic elements of box expressions."
 $basicBoxes =
 _BoxData | _TextData | _RowBox | _String | _List | _Symbol | _Rule |
 _Integer | _Real | _Complex
 
 $verbatimCodeBoxRulesLinear::usage = "\
 $verbatimCodeBoxRulesLinear \
 is a List of rules transforming \"linear\" boxes to TeX Verbatim code."
 $verbatimCodeBoxRulesLinear = {
 RowBox[l_List] :> makeString[l],
 StyleBox[contents_, ___] :> makeString[contents],
 ButtonBox[boxes_, ___] :> makeString[boxes],
 InterpretationBox[boxes_, __] :> makeString[boxes],
 FormBox[boxes_, ___] :> makeString[boxes],
 TagBox[boxes_, ___] :> makeString[boxes],
 TemplateBox[boxes_, style_, opts___] :>
 Module[{displayFunction = Replace[DisplayFunction, {opts}]},
 If[displayFunction === DisplayFunction,
 displayFunction = Replace[TemplateBoxOptionsDisplayFunction
 (* else *), 
 CurrentValue[$currentValueObj, {StyleDefinitions, style}]]
 ];
 makeString[displayFunction @@ boxes]
 ]
 }
 
 $verbatimCodeBoxHeadRulesFormatted::usage = "\
 $verbatimCodeBoxHeadRulesFormatted \
 is a List of rules assigning TeX formatting commands to box heads."
 $verbatimCodeBoxHeadRulesFormatted = {
 SubscriptBox -> "mmaSub",
 SuperscriptBox -> "mmaSup",
 SubsuperscriptBox -> "mmaSupSup",
 UnderscriptBox -> "mmaUnder",
 OverscriptBox -> "mmaOver",
 UnderoverscriptBox -> "mmaUnderOver",
 FractionBox -> "mmaFrac",
 SqrtBox -> "mmaSqrt",
 RadicalBox -> "mmaRadical"
 }
 
 $verbatimCodeSubStringRulesFormatted::usage = "\
 $verbatimCodeSubStringRulesFormatted \
 is a List of rules transforming substrings to TeX code."
 $verbatimCodeSubStringRulesFormatted = {
 "\[RightSkeleton]" -> ">>",
 char_ /; First@ToCharacterCode[char] > 126 :>
 characterToTeXVerbatimCode[char]
 }
 
 $verbatimCodeBoxRulesFormatted::usage = "\
 $verbatimCodeBoxRulesFormatted \
 is a List of rules transforming formatting boxes to TeX code."
 $verbatimCodeBoxRulesFormatted =
 Join[
 $verbatimCodeBoxRulesLinear,
 headRuleToBoxRule /@ $verbatimCodeBoxHeadRulesFormatted,
 {
 str_String :>
 StringReplace[
 makeStringDefault[str],
 Join[$verbatimCodeSubStringRulesFormatted, $commandChars]
 ]
 }
 ];
 
 
 ClearAll[linearBoxesQ]
 
 linearBoxesQ::usage = "\
 linearBoxesQ[boxes] \
 returns True if given boxes contain only \"linear\" subboxes i.e ones that \
 don't need formatting commands when exported to TeX. Returns False otherwise."
 
 linearBoxesQ[boxes_] := 
 boxesOfTypeQ[
 boxes,
 $basicBoxes | boxRulesToBoxPattern[$verbatimCodeBoxRulesLinear]
 ]
 
 
 ClearAll[boxesToTeXVerbatimCode]
 
 boxesToTeXVerbatimCode::usage = "\
 boxesToTeXVerbatimCode[boxes] \
 returns TeX verbatim code representing given boxes."
 
 boxesToTeXVerbatimCode::unspt = "Following boxes are not supported: `1`"
 
 Options[boxesToTeXVerbatimCode] = Options[boxesToString];
 SetOptions[boxesToTeXVerbatimCode,
 "BoxRules" :> $verbatimCodeBoxRulesFormatted
 ]
 
 boxesToTeXVerbatimCode[boxes_, opts : OptionsPattern[]] :=
 Module[{tag},
 Catch[
 boxesToString[
 boxes,
 DelegateOptions[
 "BoxRules" ->
 Append[
 OptionValue["BoxRules"], 
 b:Except[$basicBoxes] :> Throw[b, tag]
 ]
 ,
 opts,
 boxesToTeXVerbatimCode,
 boxesToString
 ]
 ]
 ,
 tag
 ,
 Function[{unsptBox, tagArg},
 Message[boxesToTeXVerbatimCode::unspt, unsptBox];
 $Failed
 ]
 ]
 ]
 
 
 ClearAll[optionValueToTeX]
 
 optionValueToTeX::usage = "\
 optionValueToTeX[val] \
 returns given TeX option value val suitable for inclusion as value in TeX \
 key-value argument."
 
 optionValueToTeX[val_] :=
 With[{str = ToString[val]},
 If[StringTake[str, 1] === "{" && StringTake[str, -1] === "}" || 
 StringFreeQ[str, {"[", "]", ",", "="}]
 ,
 str
 (* else *),
 "{" <> str <> "}"
 ]
 ]
 
 
 ClearAll[optionsToTeX]
 
 optionsToTeX::usage = "\
 optionsToTeX[{key1 -> val1, key2 :> val2, ...}] \
 returns String with given rules transformed to TeX key-value pairs."
 
 optionsToTeX[opts : {(Rule | RuleDelayed)[_String, _] ...}] :=
 StringJoin[Riffle[(#1 <> "=" <> optionValueToTeX[#2]) & @@@ opts, ","]]
 
 
 ClearAll[cellDataFromLabel]
 
 cellDataFromLabel::usage = "\
 cellDataFromLabel[\"cellLabel\"] \
 returns List containing three elements, extracted from given \"cellLabel\": \
 cell type (In, Out, or None), \
 cell index (Integer or None) and \
 cell form (String or None)."
 
 cellDataFromLabel[label_String] :=
 Module[{result},
 result =
 StringCases[
 label
 ,
 StartOfString ~~ "In[" ~~ i : DigitCharacter .. ~~ "]:=" ~~
 EndOfString :>
 {In, ToExpression[i], None}
 ,
 1
 ];
 If[result === {},
 result =
 StringCases[
 label
 ,
 StartOfString ~~ "Out[" ~~ i : DigitCharacter .. ~~ "]" ~~
 ("//" ~~ form__) | "" ~~ "=" ~~ EndOfString :>
 {Out, ToExpression[i], Replace[form, {"" -> None}]}
 ,
 1
 ]
 ];
 result = Flatten[result];
 If[result === {},
 {None, None, None}
 (* else *),
 result
 ]
 ]
 
 
 ClearAll[mmaCellOptionsFromLabel];
 
 mmaCellOptionsFromLabel::usage = "\
 mmaCellOptionsFromLabel[\
 showCellLabel, cellLabelFromCell, {cellLabel, cellIndex, cellForm}\
 ] \
 returns List of rules representing key-value pairs for inclusion as optional \
 argument of mmaCell TeX environment."
 
 mmaCellOptionsFromLabel[
 showCellLabel_, cellLabelFromCell_, optVals : {_, _, _}
 ] :=
 Module[
 {
 cellLabel, cellIndex, cellForm, cellTypeFromCell,
 cellIndexFromCell, cellFormFromCell
 }
 ,
 {cellLabel, cellIndex, cellForm} = optVals;
 {cellTypeFromCell, cellIndexFromCell, cellFormFromCell} = 
 cellDataFromLabel[cellLabelFromCell];
 
 If[cellTypeFromCell =!= None,
 If[cellIndex === Automatic, cellIndex = cellIndexFromCell];
 If[cellForm === Automatic, cellForm = cellFormFromCell];
 ];
 If[cellLabel === Automatic,
 If[!showCellLabel ||
 cellTypeFromCell =!= None &&
 cellIndex === cellIndexFromCell && 
 cellForm === cellFormFromCell
 ,
 cellLabel = None
 (* else *),
 cellLabel = cellLabelFromCell
 ]
 ];
 If[cellIndex === $cellIndex,
 cellIndex = None
 (* else *),
 If[IntegerQ[cellIndex], $cellIndex = cellIndex]
 ];
 DeleteCases[
 {"label" -> cellLabel, "index" -> cellIndex, "form" -> cellForm},
 _ -> None | Automatic
 ]
 ]
 
 
 ClearAll[$defaultCellStyleBoxRules, $defaultCellStyleFormatType]
 
 $defaultCellStyleBoxRules::usage = "\
 $defaultCellStyleBoxRules \
 is List of rules assigning BoxRules to particular cell styles."
 $defaultCellStyleBoxRules = {
 "Code" :> $verbatimCodeBoxRulesLinear,
 "Input" | "Output" | "Print" | "Message" :> $verbatimCodeBoxRulesFormatted
 }
 
 $defaultCellStyleFormatType::usage = "\
 $defaultCellStyleFormatType \
 is List of rules assigning String FormatType to particular cell styles."
 $defaultCellStyleFormatType = {
 "Code" | "Input" :> InputForm,
 "Output" | "Print" | "Message" :> OutputForm
 }
 
 
 ClearAll[cellContentsToTeX]
 
 cellContentsToTeX::usage = "\
 cellContentsToTeX[contents, style] \
 returns String with TeX mmaCell environment representing cell with given \
 style and contents."
 
 cellContentsToTeX::unspt = "Cell style: `1` is not supported.";
 
 Options[cellContentsToTeX] =
 Join[
 Options[boxesToTeXVerbatimCode],
 {
 "StyleBoxRules" :> $defaultCellStyleBoxRules,
 "StyleFormatType" :> $defaultCellStyleFormatType,
 "MmaCellOptions" -> {},
 "Indentation" -> " "
 }
 ];
 SetOptions[cellContentsToTeX,
 "BoxRules" -> Automatic, FormatType -> Automatic
 ]
 
 cellContentsToTeX[contents_List, style:_String, opts:OptionsPattern[]] :=
 Module[
 {
 boxRules = OptionValue["BoxRules"],
 formatType = OptionValue["FormatType"],
 mmaCellOptions = OptionValue["MmaCellOptions"]
 }
 ,
 If[boxRules === Automatic,
 boxRules = Replace[style, OptionValue["StyleBoxRules"]]
 ];
 If[formatType === Automatic,
 formatType = Replace[style, OptionValue["StyleFormatType"]]
 ];
 If[boxRules === style || formatType === style,
 Message[cellContentsToTeX::unspt, style];
 Return[$Failed]
 ];
 If[Length[ mmaCellOptions] > 0,
 mmaCellOptions = "[" <> optionsToTeX[mmaCellOptions] <> "]"
 ];
 StringJoin[
 "\\begin{mmaCell}", mmaCellOptions, "{", style, "}",
 StringReplace[
 StringJoin[
 "\n"
 , 
 boxesToTeXVerbatimCode[
 #, 
 DelegateOptions[
 FormatType -> formatType, 
 "BoxRules" -> boxRules, opts, cellContentsToTeX, 
 boxesToTeXVerbatimCode
 ]
 ]& /@
 contents
 ]
 , 
 "\n" | "\[IndentingNewLine]" ->
 "\n" <> OptionValue["Indentation"]
 ]
 ,
 "\n\\end{mmaCell}"
 ]
 ]
 cellContentsToTeX[BoxData[boxes_], style:_String, opts : OptionsPattern[]] :=
 cellContentsToTeX[boxes, style, opts]
 cellContentsToTeX[boxes_, style:_String, opts:OptionsPattern[]] :=
 cellContentsToTeX[{boxes}, style, opts]
 
 
 ClearAll[
 $cellIndex, $previousIntype, $defaultIndexedStyles, $defaultIntypeStyles
 ]
 $cellIndex = 0
 $previousIntype = False
 $defaultIndexedStyles = "Code" | "Input" | "Output"
 $defaultIntypeStyles = "Code" | "Input"
 
 
 ClearAll[cellToTeX]
 
 cellToTeX::usage = "\
 cellToTeX[cell, texStyle] \
 returns String with TeX mmaCell environment representing given cell as cell \
 with given texStyle. \
 
 cellToTeX[cell] \
 chooses texStyle based on cell style."
 
 Options[cellToTeX] =
 Join[
 Options[cellContentsToTeX],
 {
 "CellLabel" -> Automatic, "CellIndex" -> Automatic, 
 "CellForm" -> Automatic,
 "Indexed" -> Automatic, "IndexedStyles" :> $defaultIndexedStyles, 
 "IntypeStyles" :> $defaultIntypeStyles
 }
 ];
 cellToTeX[
 Cell[BoxData[boxes_], styles__String, cellOpts___?OptionQ],
 texStyle : _String | Automatic : Automatic, opts : OptionsPattern[]
 ] :=
 Module[
 {
 style, indexed, mmaCellOptions, cellOptsList, cellLabelFromCell, 
 showCellLabel, finalTeXStyle, intype
 }
 ,
 {indexed, mmaCellOptions} = OptionValue[{"Indexed", "MmaCellOptions"}];
 style = First[{styles}];
 cellOptsList = Flatten[{cellOpts}];
 cellLabelFromCell = Replace[CellLabel, {cellOpts}];
 showCellLabel = Replace[ShowCellLabel, {cellOpts}];
 finalTeXStyle = Replace[texStyle, Automatic -> style];
 
 If[indexed === Automatic,
 indexed = MatchQ[style, OptionValue["IndexedStyles"]]
 ];
 If[indexed,
 intype = MatchQ[finalTeXStyle, OptionValue["IntypeStyles"]];
 If[intype || ! $previousIntype, $cellIndex++];
 $previousIntype = intype
 ];
 If[showCellLabel === ShowCellLabel,
 showCellLabel = 
 CurrentValue[$currentValueObj,
 {StyleDefinitions, style, ShowCellLabel}
 ]
 ];
 If[cellLabelFromCell =!= CellLabel,
 mmaCellOptions =
 Join[
 mmaCellOptionsFromLabel[
 showCellLabel, cellLabelFromCell, 
 OptionValue[{"CellLabel", "CellIndex", "CellIndex"}]
 ],
 mmaCellOptions
 ];
 ];
 cellContentsToTeX[
 boxes, finalTeXStyle, 
 DelegateOptions[
 "MmaCellOptions" -> mmaCellOptions, opts, 
 cellToTeX, cellContentsToTeX
 ]
 ]
 ]


----------


# Usage examples

### Single cell
 
 testCell = 
 Cell[
 BoxData@ToBoxes[
 Subscript[x, 1] == (-b \[PlusMinus] Sqrt[b^2 - 4 a c])/(2 a)
 ],
 "Input", 
 CellLabel -> "In[153]:="
 ];
 testCell // CellPrint
 cellToTeX[testCell]
 (*
 \begin{mmaCell}[index=153]{Input}
 \mmaSub{x}{1}==\mmaFrac{-b\(\pm\)\mmaSqrt{\mmaSup{b}{2}-4 a c}}{2 a}
 \end{mmaCell}
 *)

### Whole notebook

Create a notebook with some evaluated cells:
 
 nbObj = CreateDocument[{
 Cell[BoxData@MakeBoxes[Solve[a x^2 + b x + c == 0, x]], "Input"],
 Cell[BoxData[
 Append[
 List @@ MakeBoxes /@ HoldComplete[
 Print["a \" string with double quotes inside"],
 Sin[m, n]
 ],
 RowBox[{RowBox[{"1", "+", RowBox[{"2", " ", "x"}]}], "//", "FullForm"}]]
 ],
 "Input"
 ]
 }];
 (* Switch off auto deleting of labels, so that we can extract some data from them. *)
 CurrentValue[nbObj, CellLabelAutoDelete] = False;
 SelectionMove[nbObj, All, Notebook];
 SelectionEvaluate[nbObj];

Export this notebook to TeX:
 
 ExportString[
 (* Use ordinary replacement instead of ConversionRules since the latter
 don't have access to CellLabel. *)
 NotebookGet[nbObj] /. {
 cell : Cell[BoxData[boxes_?linearBoxesQ], "Input", ___] :> 
 Cell[cellToTeX[cell, "Code"], "Final"],
 cell : Cell[_, "Input" | "Output" | "Print" | "Message", ___] :> 
 Cell[cellToTeX[cell], "Final"]
 }
 ,
 "TeXFragment",
 "ConversionRules" -> {"Final" -> Identity}
 ]
 (*
 \begin{mmaCell}[index=10]{Input}
 Solve[a \mmaSup{x}{2}+b x+c==0,x]
 \end{mmaCell}
 
 \begin{mmaCell}{Output}
 \{\{x\(\to\)\mmaFrac{-b-\mmaSqrt{\mmaSup{b}{2}-4 a c}}{2 a}\},\{x\(\to\)\mmaFrac{-b+\mmaSqrt{\mmaSup{b}{2}-4 a c}}{2 a}\}\}
 \end{mmaCell}
 
 \begin{mmaCell}{Code}
 Print["a \" string with double quotes inside"]
 Sin[m,n]
 1+2 x//FullForm
 \end{mmaCell}
 
 \begin{mmaCell}{Print}
 a " string with double quotes inside
 \end{mmaCell}
 
 \begin{mmaCell}{Message}
 Sin::argx: Sin called with 2 arguments; 1 argument is expected. >>
 \end{mmaCell}
 
 \begin{mmaCell}[index=12]{Output}
 Sin[m,n]
 \end{mmaCell}
 
 \begin{mmaCell}[form=FullForm]{Output}
 Plus[1,Times[2,x]]
 \end{mmaCell}
 *)


----------


# TODO

* Code annotations reflecting syntax highlighting ([almost finished](https://i.sstatic.net/GfDZF.png)).
* Handling of inline cells.
* Handling of graphics.
* ...