Q:

make html tags render correctly from json in angular directive template

I'm trying to insert ruby tags into a directive template.  However, I can't seem to escape them.  I've read a lot about $sce and filters and such, but there are 15 tabs open in my browser at the moment and I'm more confused than I began. 
Here is my directive:
angular.module("ngFlashCard", ["ngSanitize"]).directive("flashCardSet", [
  function() {
    return {
      scope: {
        cardGroups: "="
      },
      controller: ['$scope', function($scope) {
        $scope.selectedGroups = [];
        $scope.activeGroup = 0;
        $scope.activeCard = 0;
        $scope.shuffle = false;
        $scope.backFirst = false;

        var getRandomInt = function(min, max) {
          return Math.floor(Math.random() * (max - min + 1)) + min;
        };

        var doShuffle = function() {
          var randomIndex = getRandomInt(0, $scope.selectedGroups.length -
            1);
          var nextActive = randomIndex;
          //skip the first index so that we can do the nextActive!=randomIndex check later to avoid an infinite loop
          do {
            nextActive++;
            if (nextActive > $scope.selectedGroups.length - 1) {
              nextActive = 0;
            }
          } while ($scope.selectedGroups[nextActive] === false &&
            nextActive ! == randomIndex);
          if ($scope.selectedGroups[nextActive] === false) {
            //there are no active groups
            return;
          }
          $scope.activeGroup = nextActive;
          $scope.activeCard = getRandomInt(0, $scope.cardGroups[
            nextActive].cards.length - 1);
        };
        var setPrevious = function() {
          $scope.activeGroup--;
          if ($scope.activeGroup < 0) {
            $scope.activeGroup = $scope.cardGroups.length - 1;
          }
        };

        var doPrevious = function() {
          var lastGroup = $scope.activeGroup;
          $scope.activeCard--;
          if ($scope.activeCard < 0) {
            setPrevious();
            while ($scope.selectedGroups[$scope.activeGroup] ===
              false) {
              setPrevious();
              //only one or no active groups
              if ($scope.activeGroup === lastGroup) {
                break;
              }
            }
            $scope.activeCard = $scope.cardGroups[$scope.activeGroup]
              .cards.length - 1;
          }
        };

        $scope.previous = function() {
          if ($scope.shuffle) {
            doShuffle();
          } else {
            doPrevious();
          }
        };

        var setNext = function() {
          $scope.activeGroup++;
          if ($scope.activeGroup >= $scope.cardGroups.length) {
            $scope.activeGroup = 0;
          }
        };

        var doNext = function(nextGroup) {
          var lastGroup = $scope.activeGroup;
          $scope.activeCard++;
          if (nextGroup || $scope.activeCard >= $scope.cardGroups[
              $scope.activeGroup].cards.length) {
            $scope.activeCard = 0;
            setNext();
            while ($scope.selectedGroups[$scope.activeGroup] ===
              false) {
              setNext();
              //only one or no active groups
              if ($scope.activeGroup === lastGroup) {
                break;
              }
            }
          }
        };

        $scope.next = function(nextGroup) {
          if ($scope.shuffle) {
            doShuffle();
          } else {
            doNext(nextGroup);
          }
        };

        $scope.$watch('selectedGroups', function(newVal, oldVal, scope) {
          for (var i = 0; i < newVal.length; i++) {
            if (newVal[i] === false) {
              if (scope.activeGroup === i) {
                scope.next(true);
              }
            }
          }
        }, true);

        $scope.showFront = function(flipped) {
          return flipped ?  $scope.backFirst : ! $scope.backFirst;
        };
      }],
      template: '<div class="container-fluid ngFlashCard-cardSet ngFlashCard-fullHeight">' +
        '<div class="row ngFlashCard-fullHeight">' +
        '<ul class="ngFlashCard-groupSelector col-sm-3 list-group">' +
        '<li ng-repeat="cardGroup in cardGroups" class="list-group-item ngFlashCard-clickable" ng-init="selectedGroups[$index] = true" ' +
        'ng-click="selectedGroups[$index] = ! selectedGroups[$index]">' +
        '<input class="ngFlashCard-clickable" type="checkbox" ng-checked="selectedGroups[$index]" />{{cardGroup.name}}' +
        '</li>' +
        '</ul>' +
        '<div class="well well-sm text-center col-sm-9 ngFlashCard-fullHeight ngFlashCard-wrapper">' +
        '<div class="ngFlashCard-cardHeader">' +
        '<div class="ngFlashCard-pageButton" ng-click="previous()" >Previous</div>' +
        '<div class="ngFlashCard-clickable ngFlashCard-backFirst">' +
        '<div ng-click="backFirst = ! backFirst"><input class="ngFlashCard-clickable" type="checkbox" ng-checked="backFirst">Answers First</div>' +
        '<div ng-click="shuffle = ! shuffle"><input class="ngFlashCard-clickable" type="checkbox" ng-checked="shuffle">Shuffle</div>' +
        '</div>' +
        '<div class="ngFlashCard-pageButton" ng-click="next()" >Next</div>' +
        '</div>' +
        '<div class="ngFlashCard-cardGroup" ng-repeat="cardGroup in cardGroups" ng-if="selectedGroups[$index] && activeGroup === $index">' +
        '<div class="ngFlashCard-fullHeight" ng-repeat="card in cardGroup.cards" ng-if="activeCard === $index">' +
        '<div class="ngFlashCard-card ngFlashCard-fullHeight"' +
        'ng-class="showFront(flipped) ?  \'ngFlashCard-cardFront\' : \'ngFlashCard-cardBack\'"' +
        'ng-click="flipped = ! flipped" ng-init="flipped=false">' +
        "<h1>{{showFront(flipped) ?  card.front : card.back }}</h1>" +
        '</div>' +
        '</div>' +
        '</div>' +
        '<span>{{cardGroups[activeGroup].name}}</span>' +
        '</div>' +
        '</div>' +
        '</div>'
    };
  }
]);

A sample page:
<! DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>ngFlashCard Sample</title>
    <script src="../bower_components/angular/angular.js"></script>
    <script src="../bower_components/angular-sanitize/angular-sanitize.js"></script>
    <script src="../dist/ngFlashCard.js"></script>
    <link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css">
    <link rel="stylesheet" href="../dist/ngFlashCard.min.css"/>
    <script>
        angular.module("testModule",['ngFlashCard', 'ngSanitize']).run(['$rootScope',function($rootScope){
            $rootScope.exampleCardGroups =[
                {name: "Chapter 2", cards: [
                    {front: "お金", back:"お<ruby>金<rp>（</rp><rt>かね</rt><rp>）</rp></ruby>"},
                    {front: "お土産", back:"<ruby>土産<rp>（</rp><rt>みやげ</rt><rp>）</rp></ruby>"},
                    {front: "温泉", back:"<ruby>温<rp>（</rp><rt>おん</rt><rp>）</rp></ruby><ruby>泉<rp>（</rp><rt>せん</rt><rp>）</rp></ruby>"},
                    {front: "海外", back:"<ruby>海<rp>（</rp><rt>かい</rt><rp>）</rp></ruby><ruby>外<rp>（</rp><rt>がい</rt><rp>）</rp></ruby>"}
                ]}
            ];
        }]);
    </script>
</head>
<body ng-app="testModule" >
   <div class="text-center " flash-card-set card-groups="exampleCardGroups" style="padding:15px"></div>
</body>
</html

Basically, I want to load the "back" data into the h1 as html. 

A:

please run the below snippet.  I hope this is what you're looking for.  

// Code goes here
angular.module("ngFlashCard", ["ngSanitize"]).directive("flashCardSet", [
  function() {
    return {
      scope: {
        cardGroups: "="
      },
      controller: ['$scope',
        function($scope) {
          $scope.selectedGroups = [];
          $scope.activeGroup = 0;
          $scope.activeCard = 0;
          $scope.shuffle = false;
          $scope.backFirst = false;

          var getRandomInt = function(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
          };

          var doShuffle = function() {
            var randomIndex = getRandomInt(0, $scope.selectedGroups.length -
              1);
            var nextActive = randomIndex;
            //skip the first index so that we can do the nextActive!=randomIndex check later to avoid an infinite loop
            do {
              nextActive++;
              if (nextActive > $scope.selectedGroups.length - 1) {
                nextActive = 0;
              }
            } while ($scope.selectedGroups[nextActive] === false &&
              nextActive ! == randomIndex);
            if ($scope.selectedGroups[nextActive] === false) {
              //there are no active groups
              return;
            }
            $scope.activeGroup = nextActive;
            $scope.activeCard = getRandomInt(0, $scope.cardGroups[
              nextActive].cards.length - 1);
          };
          var setPrevious = function() {
            $scope.activeGroup--;
            if ($scope.activeGroup < 0) {
              $scope.activeGroup = $scope.cardGroups.length - 1;
            }
          };

          var doPrevious = function() {
            var lastGroup = $scope.activeGroup;
            $scope.activeCard--;
            if ($scope.activeCard < 0) {
              setPrevious();
              while ($scope.selectedGroups[$scope.activeGroup] ===
                false) {
                setPrevious();
                //only one or no active groups
                if ($scope.activeGroup === lastGroup) {
                  break;
                }
              }
              $scope.activeCard = $scope.cardGroups[$scope.activeGroup]
                .cards.length - 1;
            }
          };

          $scope.previous = function() {
            if ($scope.shuffle) {
              doShuffle();
            } else {
              doPrevious();
            }
          };

          var setNext = function() {
            $scope.activeGroup++;
            if ($scope.activeGroup >= $scope.cardGroups.length) {
              $scope.activeGroup = 0;
            }
          };

          var doNext = function(nextGroup) {
            var lastGroup = $scope.activeGroup;
            $scope.activeCard++;
            if (nextGroup || $scope.activeCard >= $scope.cardGroups[
              $scope.activeGroup].cards.length) {
              $scope.activeCard = 0;
              setNext();
              while ($scope.selectedGroups[$scope.activeGroup] ===
                false) {
                setNext();
                //only one or no active groups
                if ($scope.activeGroup === lastGroup) {
                  break;
                }
              }
            }
          };

          $scope.next = function(nextGroup) {
            if ($scope.shuffle) {
              doShuffle();
            } else {
              doNext(nextGroup);
            }
          };

          $scope.$watch('selectedGroups', function(newVal, oldVal, scope) {
            for (var i = 0; i < newVal.length; i++) {
              if (newVal[i] === false) {
                if (scope.activeGroup === i) {
                  scope.next(true);
                }
              }
            }
          }, true);

          $scope.showFront = function(flipped) {
            return flipped ?  $scope.backFirst : ! $scope.backFirst;
          };
        }
      ],
      template: '<div class="container-fluid ngFlashCard-cardSet ngFlashCard-fullHeight">' +
        '<div class="row ngFlashCard-fullHeight">' +
        '<ul class="ngFlashCard-groupSelector col-sm-3 list-group">' +
        '<li ng-repeat="cardGroup in cardGroups" class="list-group-item ngFlashCard-clickable" ng-init="selectedGroups[$index] = true" ' +
        'ng-click="selectedGroups[$index] = ! selectedGroups[$index]">' +
        '<input class="ngFlashCard-clickable" type="checkbox" ng-checked="selectedGroups[$index]" />{{cardGroup.name}}' +
        '</li>' +
        '</ul>' +
        '<div class="well well-sm text-center col-sm-9 ngFlashCard-fullHeight ngFlashCard-wrapper">' +
        '<div class="ngFlashCard-cardHeader">' +
        '<div class="ngFlashCard-pageButton" ng-click="previous()" >Previous</div>' +
        '<div class="ngFlashCard-clickable ngFlashCard-backFirst">' +
        '<div ng-click="backFirst = ! backFirst"><input class="ngFlashCard-clickable" type="checkbox" ng-checked="backFirst">Answers First</div>' +
        '<div ng-click="shuffle = ! shuffle"><input class="ngFlashCard-clickable" type="checkbox" ng-checked="shuffle">Shuffle</div>' +
        '</div>' +
        '<div class="ngFlashCard-pageButton" ng-click="next()" >Next</div>' +
        '</div>' +
        '<div class="ngFlashCard-cardGroup" ng-repeat="cardGroup in cardGroups" ng-if="selectedGroups[$index] && activeGroup === $index">' +
        '<div class="ngFlashCard-fullHeight" ng-repeat="card in cardGroup.cards" ng-if="activeCard === $index">' +
        '<div class="ngFlashCard-card ngFlashCard-fullHeight"' +
        'ng-class="showFront(flipped) ?  \'ngFlashCard-cardFront\' : \'ngFlashCard-cardBack\'"' +
        'ng-click="flipped = ! flipped" ng-init="flipped=false">' +
        '<h1 ng-bind-html="showFront(flipped) ?  card.front : card.back"></h1>' +
        '</div>' +
        '</div>' +
        '</div>' +
        '<span>{{cardGroups[activeGroup].bind-htmlname}}</span>' +
        '</div>' +
        '</div>' +
        '</div>'
    };
  }
]);
<! DOCTYPE html>
<html>

<head>
  <script data-require="angularjs@1.5.5" data-semver="1.5.5" src="https://code.angularjs.org/1.5.5/angular.js"></script>
  <script data-require="angular-sanitize@1.5.5" data-semver="1.5.5" src="https://code.angularjs.org/1.5.5/angular-sanitize.js"></script>
  <script src="script.js"></script>
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-app="testModule">
  <h1>Hello Plunker!</h1>
  <meta charset="UTF-8" />
  <title>ngFlashCard Sample</title>
  <script src="script.js"></script>
  <script>
    angular.module("testModule", ['ngFlashCard']).run(['$rootScope',
      function($rootScope) {
        $rootScope.exampleCardGroups = [{
          name: "Chapter 2",
          cards: [{
            front: "お金",
            back: "お<ruby>金<rp>（</rp><rt>かね</rt><rp>）</rp></ruby>"
          }, {
            front: "お土産",
            back: "<ruby>土産<rp>（</rp><rt>みやげ</rt><rp>）</rp></ruby>"
          }, {
            front: "温泉",
            back: "<ruby>温<rp>（</rp><rt>おん</rt><rp>）</rp></ruby><ruby>泉<rp>（</rp><rt>せん</rt><rp>）</rp></ruby>"
          }, {
            front: "海外",
            back: "<ruby>海<rp>（</rp><rt>かい</rt><rp>）</rp></ruby><ruby>外<rp>（</rp><rt>がい</rt><rp>）</rp></ruby>"
          }]
        }];
      }
    ]);
  </script>
  <div class="text-center " flash-card-set="" card-groups="exampleCardGroups" style="padding:15px"></div>
</body>

</html>

The only change I did to run  tags in html is 
'<h1 ng-bind-html="showFront(flipped) ?  card.front : card.back"></h1>'

I hope it will help you.  
Cheers!