Text formatting?

Says who? You just defined your intermediate format.

export interface Block {
  flavor: 'title' | 'subtitle' | 'content' | 'img' | 'list' | 'listitem' | 'boxout' | 'links' | 'link';
  contents: string | Block[];
  description?: string;
}

export interface Product {
  blocks: Block[];
}

products:Product[] = [
  {blocks: [
  {flavor: 'title', contents: 'Title'},
  {flavor: 'subtitle', contents: 'Subtitle'},
  {flavor: 'content', contents: 'Content'},
  {flavor: 'img', contents: 'http://url/img.png'},
  {flavor: 'content': contents: 'Content'},
  {flavor: 'subtitle', contents: 'Subtitle'},
  {flavor: 'list', contents: [{flavor: 'listitem', contents: 'li1'}]},
  ]},
  {blocks: [
  {flavor: 'title', contents: 'Title'},
  {flavor: 'subtitle', contents: 'SubTitle'},
  {flavor: 'list', contents: [{flavor: 'listitem', contents: 'li1'}]},
  {flavor: 'boxout', contents: 'Boxout'},
  {flavor: 'img', contents: 'http://url/img.png'},
  {flavor: 'subtitle', contents: 'Subtitle'},
  {flavor: 'content', contents: 'Content'},
  {flavor: 'links', contents: [{flavor: 'link', contents: 'http//url', description: 'cool link'}]},
  ]},
];

<ion-card *ngFor="let product of products">
<ng-template ngFor let-block [ngForOf]="product.blocks">
<h1 *ngIf="block.flavor === 'title'">{{block.contents}}</h1>
<h2 *ngIf="block.flavor === 'subtitle'">{{block.contents}}</h2>
<span *ngIf="block.flavor === 'contents'">{{block.contents}}<span>
<img [src]="block.contents" *ngIf="block.flavor === 'img'">
<ul *ngIf="block.flavor === 'list'">
  <li *ngFor="let li of block.contents">{{li.contents}}</li>
</ul>
<div class="boxout" *ngIf="block.flavor === 'boxout'">{{block.contents}}</div>
<div class="links" *ngIf="block.flavor === 'links'">
  <div *ngFor="let link of block.contents">
    <a [href]="block.contents">{{block.description}}</a>
  </div>
</div>
</ng-template>
</ion-card>