From b477fd11bc8ff4d22fc65f08a4a174749a5daefa Mon Sep 17 00:00:00 2001
From: "Tate, Hongliang Tian" <tatetian@gmail.com>
Date: Wed, 25 Feb 2015 19:26:30 +0800
Subject: [PATCH] Add font command support

---
 PseudoCode.js      | 61 +++++++++++++++++++++++++++++++++-------------
 css/PseudoCode.css | 12 ++++++---
 static.html        |  5 +++-
 3 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/PseudoCode.js b/PseudoCode.js
index 235a565..c9a0d4f 100644
--- a/PseudoCode.js
+++ b/PseudoCode.js
@@ -77,9 +77,8 @@ closely mirrors that of the grammar.
 
 TODO:
     * comment
-    * fonts: \bf, \textbf{} ...
-    * size: \large, ...
     * noend
+    * color{#FF0000}{text}
     * line number every k lines: \begin{algorithmic}[k]
     * caption without the number: \caption*{}
     * rename: e.g. require --> input, ensure --> output
@@ -587,10 +586,15 @@ Parser.prototype._parseSymbol = function() {
     else if (text = this._lexer.accept('func',
         ['rmfamily', 'sffamily', 'ttfamily',
          'upshape', 'itshape', 'slshape', 'scshape',
-         'bfseries', 'mdseries', 'lfseries',
-         'uppercase', 'lowercase'])) {
+         'bfseries', 'mdseries', 'lfseries'])) {
         return new ParseNode('font-dclr', text);
     }
+    else if (text = this._lexer.accept('func',
+        ['textnormal', 'textrm', 'textsf', 'texttt', 'textup', 'textit',
+        'textsl', 'textsc', 'uppercase', 'lowercase', 'textbf', 'textmd',
+        'textlf'])) {
+        return new ParseNode('font-cmd', text);
+    }
     return null;
 }
 
@@ -635,8 +639,9 @@ function TextStyle(outerTextStyle) {
     cmd - the name of TeX command that alters current font
 */
 TextStyle.prototype._fontCommandTable = {
+    // -------------- declaration --------------
     // font-family
-    rmfamily: { 'font-family': 'KaTeX_Main' },
+    rmfamily: { 'font-family': 'KaTeX_Main'},
     sffamily: { 'font-family': 'KaTeX_SansSerif'},
     ttfamily: { 'font-family': 'KaTeX_Typewriter'},
     // weight
@@ -648,6 +653,20 @@ TextStyle.prototype._fontCommandTable = {
     itshape: { 'font-style': 'italic', 'font-variant': 'normal'},
     scshape: { 'font-style': 'normal', 'font-variant': 'small-caps'},
     slshape: { 'font-style': 'oblique', 'font-variant': 'normal'},
+    // -------------- command --------------
+    // font-family
+    textrm: { 'font-family': 'KaTeX_Main'},
+    textsf: { 'font-family': 'KaTeX_SansSerif'},
+    texttt: { 'font-family': 'KaTeX_Typewriter'},
+    // weight
+    textbf: { 'font-weight': 'bold'},
+    textmd: { 'font-weight': 'medium'},
+    textlf: { 'font-weight': 'lighter'},
+    // shape
+    textup: { 'font-style': 'normal', 'font-variant': 'normal'},
+    textit: { 'font-style': 'italic', 'font-variant': 'normal'},
+    textsc: { 'font-style': 'normal', 'font-variant': 'small-caps'},
+    textsl: { 'font-style': 'oblique', 'font-variant': 'normal'},
     // case
     uppercase: { 'text-transform': 'uppercase'},
     lowercase: { 'text-transform': 'lowercase'}
@@ -701,15 +720,9 @@ TextStyle.prototype.toCSS = function() {
     return cssStr;
 };
 
-function TextEnvironment(nodes, open, outerTextStyle) {
+function TextEnvironment(nodes, textStyle) {
     this._nodes = nodes;
-    this._outerTextStyle = outerTextStyle;
-
-    // For an close text environment, text-style changes should only take
-    // effect inside the environment. Thus, we should NOT modify
-    // `outerTextStyle`. In contrast, for an open text environment, we make all
-    // the updates on outerTextStyle directly.
-    this._textStyle = open ? outerTextStyle : new TextStyle(outerTextStyle);
+    this._textStyle = textStyle;
 }
 
 TextEnvironment.prototype.renderToHTML = function() {
@@ -743,7 +756,8 @@ TextEnvironment.prototype.renderToHTML = function() {
             this._html.putText(replaceStr);
             break;
         case 'close-text':
-            var textEnv = new TextEnvironment(node.children, false, this._textStyle);
+            var newTextStyle = new TextStyle();
+            var textEnv = new TextEnvironment(node.children, newTextStyle);
             this._html.putSpan(textEnv.renderToHTML());
             break;
         // There are two kinds of typestyle commands:
@@ -769,7 +783,19 @@ TextEnvironment.prototype.renderToHTML = function() {
             var cmdName = node.value;
             this._textStyle.updateByCommand(cmdName);
             this._html.beginSpan(null, this._textStyle.toCSS());
-            var textEnv = new TextEnvironment(this._nodes, true, this._textStyle);
+            var textEnv = new TextEnvironment(this._nodes, this._textStyle);
+            this._html.putSpan(textEnv.renderToHTML());
+            this._html.endSpan();
+            break;
+        case 'font-cmd':
+            var textNode = this._nodes[0];
+            if (textNode.type !== 'close-text') continue;
+
+            var cmdName = node.value;
+            var innerTextStyle = new TextStyle();
+            innerTextStyle.updateByCommand(cmdName);
+            this._html.beginSpan(null, innerTextStyle.toCSS());
+            var textEnv = new TextEnvironment(textNode.children, innerTextStyle);
             this._html.putSpan(textEnv.renderToHTML());
             this._html.endSpan();
             break;
@@ -1201,11 +1227,12 @@ Renderer.prototype._buildTree = function(node) {
         break;
     // ------------------- Text -------------------
     case 'open-text':
-        var textEnv = new TextEnvironment(node.children, true, this._globalTextStyle);
+        var textEnv = new TextEnvironment(node.children, this._globalTextStyle);
         this._html.putSpan(textEnv.renderToHTML());
         break;
     case 'close-text':
-        var textEnv = new TextEnvironment(node.children, false, this._globalTextStyle);
+        var newTextStyle = new TextStyle();
+        var textEnv = new TextEnvironment(node.children, newTextStyle);
         this._html.putSpan(textEnv.renderToHTML());
         break;
     default:
diff --git a/css/PseudoCode.css b/css/PseudoCode.css
index 8289ef5..08ca949 100644
--- a/css/PseudoCode.css
+++ b/css/PseudoCode.css
@@ -22,15 +22,19 @@
     margin: 0; padding: 0;
     line-height: 1.2;
 }
-.ps-root .ps-line > span {
-}
 .ps-root .ps-funcname {
     font-family: serif;
+    font-weight: normal;
     font-variant: small-caps;
+    font-style: normal;
+    text-transform: none;
 }
-/* keyword */
 .ps-root .ps-keyword {
-    font-weight: 700;
+    font-family: KaTeX_Main;
+    font-weight: bold;
+    font-variant: normal;
+    font-style: normal;
+    text-transform: none;
     margin: 0 0.25em;
 }
 .ps-root .ps-keyword:first-child{
diff --git a/static.html b/static.html
index 2de2b87..ce5d908 100644
--- a/static.html
+++ b/static.html
@@ -18,16 +18,19 @@
         \begin{algorithmic}
         \REQUIRE  {asd}{jios}{adf} jioasdfjioas aijosfaisjo asjdf asjoi asdfasdf jo asdjd j asdjo $n \geq 0$
         \ENSURE $y = x^n$
+        \STATE pre \textbf{bold text} after
+        \STATE pre \texttt{typewriter} after
         \STATE  asjo aosd j asodij jdsf $y \leftarrow 1$ a js j djioas jo j
         \STATE Test text-style commands:
         \STATE different font-family: {\sffamily sffamily \ttfamily ttfamily \rmfamily rmfamily}
         \STATE different wieghts: {normal weight \bfseries bold \mdseries medium \lfseries lighter}
         \STATE different shapes: {\itshape itshape \scshape Small-Caps \slshape slshape \upshape upshape}
         \STATE {normal text vs. \slshape after slshape}
-        \STATE {\uppercase all is uppercase} vs. {\lowercase ALL lOWER Case}
+        \STATE \uppercase{ all is uppercase} vs. \lowercase{ ALL lOWER Case}
         \STATE sizing {\tiny tiny \scriptsize scriptsize \footnotesize
             footnotesize \small small \normalsize normal \large large \Large Large
             \LARGE LARGE \huge huge \Huge Huge}
+        \STATE from here, everything is \ttfamily ttfamily
         \STATE $X \leftarrow x$
         \STATE $N \leftarrow n$
         \WHILE{$N \neq 0$}
-- 
GitLab