diff --git a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.html b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.html
index b8d222ea2349d0e2977dfca00fc09d2b04354037..a2489068f100c7f1c4db88f3aa763b73658debe6 100644
--- a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.html
+++ b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.html
@@ -23,7 +23,10 @@
                            [maxDataCharacters]="data.maxDataCharacters"
                            [isModerator]="data.isModerator"
                            [isEditor]="true"
-                           [currentData]="improvedValue.body"></app-view-comment-data>
+                           [currentData]="improvedValue.body"
+                           [usesFormality]="true"
+                           [formalityEmitter]="onFormalityChange.bind(this)"
+                           [selectedFormality]="'less'"></app-view-comment-data>
   </mat-radio-group>
 </div>
 
diff --git a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts
index 2ccabc9798128b53f7e556277035ba5fbc1ceda0..b28a0db8cf4a968bcf964ea49a682ef965d641ae 100644
--- a/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts
+++ b/src/app/components/shared/_dialogs/deep-ldialog/deep-ldialog.component.ts
@@ -6,6 +6,10 @@ import { LanguageService } from '../../../../services/util/language.service';
 import { TranslateService } from '@ngx-translate/core';
 import { WriteCommentComponent } from '../../write-comment/write-comment.component';
 import { ExplanationDialogComponent } from '../explanation-dialog/explanation-dialog.component';
+import { DeepLService, FormalityType, TargetLang } from '../../../../services/http/deep-l.service';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { Target } from '@angular/compiler';
 
 interface ResultValue {
   body: string;
@@ -25,6 +29,7 @@ export class DeepLDialogComponent implements OnInit, AfterViewInit {
   radioButtonValue: ResultValue;
   normalValue: ResultValue;
   improvedValue: ResultValue;
+  supportsFormality: boolean;
 
   constructor(
     private dialogRef: MatDialogRef<DeepLDialogComponent>,
@@ -32,10 +37,51 @@ export class DeepLDialogComponent implements OnInit, AfterViewInit {
     private notificationService: NotificationService,
     private languageService: LanguageService,
     private translateService: TranslateService,
+    private deeplService: DeepLService,
     private dialog: MatDialog) {
     this.languageService.langEmitter.subscribe(lang => {
       this.translateService.use(lang);
     });
+    this.supportsFormality = DeepLService.supportsFormality(this.data.target);
+  }
+
+  public static generateDeeplDelta(deepl: DeepLService, body: string, targetLang: TargetLang,
+                                   formality = FormalityType.less): Observable<[string, string]> {
+    const delta = ViewCommentDataComponent.getDeltaFromData(body);
+    const xml = delta.ops.reduce((acc, e, i) => {
+      if (typeof e['insert'] === 'string' && e['insert'].trim().length) {
+        acc += '<x i="' + i + '">' + this.encodeHTML(e['insert']) + '</x>';
+        e['insert'] = '';
+      }
+      return acc;
+    }, '');
+    return deepl.improveTextStyle(xml, targetLang, formality).pipe(
+      map(str => {
+        const regex = /<x i="(\d+)">([^<]+)<\/x>/gm;
+        let m;
+        while ((m = regex.exec(str)) !== null) {
+          delta.ops[+m[1]]['insert'] += this.decodeHTML(m[2]);
+        }
+        const text = delta.ops.reduce((acc, el) => acc + (typeof el['insert'] === 'string' ? el['insert'] : ''), '');
+        return [ViewCommentDataComponent.getDataFromDelta(delta), text];
+      })
+    );
+  }
+
+  private static encodeHTML(str: string): string {
+    return str.replace(/&/g, '&amp;')
+      .replace(/</g, '&lt;')
+      .replace(/>/g, '&gt;')
+      .replace(/"/g, '&quot;')
+      .replace(/'/g, '&apos;');
+  }
+
+  private static decodeHTML(str: string): string {
+    return str.replace(/&apos;/g, '\'')
+      .replace(/&quot;/g, '"')
+      .replace(/&gt;/g, '>')
+      .replace(/&lt;/g, '<')
+      .replace(/&amp;/g, '&');
   }
 
   ngOnInit(): void {
@@ -80,7 +126,7 @@ export class DeepLDialogComponent implements OnInit, AfterViewInit {
       if (WriteCommentComponent.checkInputData(current.body, current.text,
         this.translateService, this.notificationService, this.data.maxTextCharacters, this.data.maxDataCharacters)) {
         this.data.onClose(current.body, current.text, current.view);
-        this.dialogRef.close();
+        this.dialogRef.close(true);
       }
     };
   }
@@ -92,4 +138,18 @@ export class DeepLDialogComponent implements OnInit, AfterViewInit {
     ref.componentInstance.translateKey = 'explanation.deepl';
   }
 
+  onFormalityChange(formality: string) {
+    DeepLDialogComponent.generateDeeplDelta(this.deeplService, this.data.body, this.data.usedTarget, formality as FormalityType)
+      .subscribe(([improvedBody, improvedText]) => {
+        console.log(improvedBody, improvedText);
+        this.improvedValue.body = improvedBody;
+        this.improvedValue.text = improvedText;
+        this.improved.currentData = improvedBody;
+      }, (_) => {
+        this.translateService.get('deepl-formality-select.error').subscribe(str => {
+          this.notificationService.show(str);
+        });
+      });
+  }
+
 }
diff --git a/src/app/components/shared/_dialogs/quill-input-dialog/quill-input-dialog.component.ts b/src/app/components/shared/_dialogs/quill-input-dialog/quill-input-dialog.component.ts
index 208868b77ec9d1298c41f7c9cb7881c793dfaa7f..e054bde4f3a204390a0769a73e98fa29917b6985 100644
--- a/src/app/components/shared/_dialogs/quill-input-dialog/quill-input-dialog.component.ts
+++ b/src/app/components/shared/_dialogs/quill-input-dialog/quill-input-dialog.component.ts
@@ -8,7 +8,7 @@ interface DialogData {
   meta: string;
   quill: any;
   selection: any;
-  overrideAction?: (value: string) => void;
+  overrideAction?: (value: string, selection: any) => void;
 }
 
 @Component({
@@ -52,7 +52,7 @@ export class QuillInputDialogComponent implements OnInit {
   buildConfirmAction() {
     return () => {
       if (this.data.overrideAction) {
-        this.data.overrideAction(this.value);
+        this.data.overrideAction(this.value, this.data.selection);
         this.dialogRef.close();
         return;
       }
diff --git a/src/app/components/shared/view-comment-data/view-comment-data.component.html b/src/app/components/shared/view-comment-data/view-comment-data.component.html
index 75dd3999eef1096d7195f226f3a80904c96509e6..1220e9869b34912a367a3511c0096a91cef6a22f 100644
--- a/src/app/components/shared/view-comment-data/view-comment-data.component.html
+++ b/src/app/components/shared/view-comment-data/view-comment-data.component.html
@@ -5,6 +5,10 @@
                 [modules]="quillModules"
                 (document:click)="onDocumentClick($event)"
                 (window:resize)="recalcAspectRatio()">
+    <div quill-editor-toolbar>
+      <ng-container [ngTemplateOutlet]="isModerator ? moderatorToolbar : participantToolbar">
+      </ng-container>
+    </div>
   </quill-editor>
   <div #tooltipContainer></div>
   <div fxLayout="row" style="justify-content: flex-end; padding: 0 5px">
@@ -17,3 +21,64 @@
   <quill-view #quillView [modules]="quillModules" (window:resize)="recalcAspectRatio()">
   </quill-view>
 </div>
+
+<ng-template #participantToolbar>
+  <span class="ql-formats">
+    <button type="button" class="ql-bold"></button>
+    <button type="button" class="ql-list" value="bullet"></button>
+    <button type="button" class="ql-list" value="ordered"></button>
+    <button type="button" class="ql-blockquote"></button>
+    <button type="button" class="ql-link" (click)="onClick($event, 'link')"></button>
+    <button type="button" class="ql-code-block"></button>
+    <button type="button" class="ql-formula" (click)="onClick($event, 'formula')"></button>
+    <button type="button" class="ql-emoji" *ngIf="hasEmoji"></button>
+    <mat-form-field class="deepl-form-field" *ngIf="usesFormality">
+      <mat-label>
+        <mat-icon class="icon-svg"></mat-icon>
+        {{'deepl-formality-select.name' | translate}}
+      </mat-label>
+      <label for="deeplFormality">
+        {{selectedFormality && ('deepl-formality-select.' + selectedFormality | translate)}}
+      </label>
+      <mat-select id="deeplFormality" [(ngModel)]="selectedFormality"
+                  (selectionChange)="formalityEmitter && formalityEmitter(selectedFormality)">
+        <mat-option>{{'deepl-formality-select.reset' | translate}}</mat-option>
+        <mat-option value="default">{{'deepl-formality-select.default' | translate}}</mat-option>
+        <mat-option value="less">{{'deepl-formality-select.less' | translate}}</mat-option>
+        <mat-option value="more">{{'deepl-formality-select.more' | translate}}</mat-option>
+      </mat-select>
+    </mat-form-field>
+  </span>
+</ng-template>
+
+<ng-template #moderatorToolbar>
+  <span class="ql-formats">
+    <button type="button" class="ql-bold"></button>
+    <select class="ql-color"></select>
+    <button type="button" class="ql-strike"></button>
+    <button type="button" class="ql-list" value="bullet"></button>
+    <button type="button" class="ql-list" value="ordered"></button>
+    <button type="button" class="ql-blockquote"></button>
+    <button type="button" class="ql-link" (click)="onClick($event, 'link')"></button>
+    <button type="button" class="ql-image" (click)="onClick($event, 'image')"></button>
+    <button type="button" class="ql-video" (click)="onClick($event, 'video')"></button>
+    <button type="button" class="ql-code-block"></button>
+    <button type="button" class="ql-formula" (click)="onClick($event, 'formula')"></button>
+    <button type="button" class="ql-emoji" *ngIf="hasEmoji"></button>
+    <mat-form-field class="deepl-form-field" *ngIf="usesFormality">
+      <mat-label>
+        <mat-icon class="icon-svg"></mat-icon>
+        {{'deepl-formality-select.name' | translate}}
+      </mat-label>
+      <label for="deeplFormality">
+        {{selectedFormality && ('deepl-formality-select.' + selectedFormality | translate)}}
+      </label>
+      <mat-select id="deeplFormality" [(ngModel)]="selectedFormality"
+                  (selectionChange)="formalityEmitter && formalityEmitter(selectedFormality)">
+        <mat-option value="default">{{'deepl-formality-select.default' | translate}}</mat-option>
+        <mat-option value="less">{{'deepl-formality-select.less' | translate}}</mat-option>
+        <mat-option value="more">{{'deepl-formality-select.more' | translate}}</mat-option>
+      </mat-select>
+    </mat-form-field>
+  </span>
+</ng-template>
diff --git a/src/app/components/shared/view-comment-data/view-comment-data.component.scss b/src/app/components/shared/view-comment-data/view-comment-data.component.scss
index dcf3fc961a68a77048a5f8af2cc74c3d50662ac4..bc2014cd318b9ea1cbc623a6fd7fbf0d6893da7c 100644
--- a/src/app/components/shared/view-comment-data/view-comment-data.component.scss
+++ b/src/app/components/shared/view-comment-data/view-comment-data.component.scss
@@ -142,3 +142,49 @@
     }
   }
 }
+
+#deeplFormality {
+  display: inline;
+}
+
+.deepl-form-field {
+  @media screen and (max-width: 500px) {
+    width: 70px;
+  }
+  z-index: 10000;
+  height: 1em;
+}
+
+::ng-deep .deepl-form-field .mat-form-field-wrapper {
+  position: absolute;
+  top: -1.35em;
+  left: 10px;
+
+  @media only screen and (max-device-width: 480px) and (orientation: portrait),
+  only screen and (max-device-height: 480px) and (orientation: landscape) {
+    width: 70px;
+    top: -1em;
+    left: 0;
+  }
+}
+
+.anchor-right {
+  @media screen and (max-width: 500px) {
+    width: 70px;
+    left: calc(100% - 70px);
+  }
+  width: 200px;
+  height: 50px;
+  position: relative;
+  left: calc(100% - 200px);
+  top: 0;
+}
+
+.anchor-wrp {
+  width: calc(100% - 200px);
+  display: inline-block;
+  height: 0;
+  position: relative;
+  left: 0;
+  top: 0;
+}
diff --git a/src/app/components/shared/view-comment-data/view-comment-data.component.ts b/src/app/components/shared/view-comment-data/view-comment-data.component.ts
index 9098e0ddda94e15cc0826e0840e3ed7a7439c72d..1b570f892e530a93c2105f52d88e9dd4f6fee4d5 100644
--- a/src/app/components/shared/view-comment-data/view-comment-data.component.ts
+++ b/src/app/components/shared/view-comment-data/view-comment-data.component.ts
@@ -1,4 +1,11 @@
-import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
+import {
+  AfterViewInit,
+  Component,
+  ElementRef,
+  Input,
+  OnInit,
+  ViewChild,
+} from '@angular/core';
 import { QuillEditorComponent, QuillModules, QuillViewComponent } from 'ngx-quill';
 import Delta from 'quill-delta';
 import Quill from 'quill';
@@ -14,15 +21,6 @@ import { LanguagetoolResult } from '../../../services/http/languagetool.service'
 
 Quill.register('modules/imageResize', ImageResize);
 
-const participantToolbar = [
-  ['bold', { list: 'bullet' }, { list: 'ordered' }, 'blockquote', 'link', 'code-block', 'formula', 'emoji']
-];
-
-const moderatorToolbar = [
-  ['bold', { color: [] }, 'strike', { list: 'bullet' }, { list: 'ordered' }, 'blockquote',
-    'link', 'image', 'video', 'code-block', 'formula', 'emoji'],
-];
-
 @Component({
   selector: 'app-view-comment-data',
   templateUrl: './view-comment-data.component.html',
@@ -53,18 +51,12 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit {
   @Input() maxDataCharacters = 1500;
   @Input() placeHolderText = '';
   @Input() afterEditorInit?: () => void;
+  @Input() usesFormality = false;
+  @Input() formalityEmitter: (string) => void;
+  @Input() selectedFormality = 'default';
   currentText = '\n';
-  quillModules: QuillModules = {
-    toolbar: {
-      container: participantToolbar,
-      handlers: {
-        image: () => this.handle('image'),
-        video: () => this.handle('video'),
-        link: () => this.handle('link'),
-        formula: () => this.handle('formula')
-      }
-    }
-  };
+  quillModules: QuillModules = {};
+  hasEmoji = true;
   private _currentData = null;
   private _marks: Marks;
 
@@ -118,9 +110,6 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit {
 
 
   ngOnInit(): void {
-    if (this.isModerator) {
-      this.quillModules.toolbar['container'] = moderatorToolbar;
-    }
     const isMobile = this.deviceInfo.isUserAgentMobile;
     if (this.isEditor) {
       this.quillModules['emoji-toolbar'] = !isMobile;
@@ -128,6 +117,7 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit {
       this.quillModules.imageResize = {
         modules: ['Resize', 'DisplaySize']
       };
+      this.hasEmoji = !isMobile;
     }
     this.translateService.use(localStorage.getItem('currentLang'));
     if (this.isEditor) {
@@ -242,9 +232,16 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit {
     this._marks.copy(viewCommentData._marks);
   }
 
+  public onClick(e: MouseEvent, type) {
+    e.preventDefault();
+    e.stopImmediatePropagation();
+    this.handle(type);
+    return false;
+  }
+
   private overrideQuillTooltip() {
     const tooltip = this.editor.quillEditor.theme.tooltip;
-    const prev = tooltip.show;
+    const prev = tooltip.show.bind(tooltip);
     let range;
     tooltip.show = () => {
       const sel = this.editor.quillEditor.getSelection(false);
@@ -263,7 +260,7 @@ export class ViewCommentDataComponent implements OnInit, AfterViewInit {
           currentSize += 1;
         }
       }
-      prev.bind(tooltip)();
+      prev();
     };
     tooltip.edit = (type: string, value: string) => {
       this.handle(type, value, (val: string) => {
diff --git a/src/app/components/shared/write-comment/write-comment.component.ts b/src/app/components/shared/write-comment/write-comment.component.ts
index e0aaf9bd6535cf53598225584f45663d8f9b6507..66ec29e4ba6468c9ead49761b6afccac575a350c 100644
--- a/src/app/components/shared/write-comment/write-comment.component.ts
+++ b/src/app/components/shared/write-comment/write-comment.component.ts
@@ -7,8 +7,6 @@ import { EventService } from '../../../services/util/event.service';
 import { LanguageService } from '../../../services/util/language.service';
 import { ViewCommentDataComponent } from '../view-comment-data/view-comment-data.component';
 import { DeepLService, SourceLang, TargetLang } from '../../../services/http/deep-l.service';
-import { Observable } from 'rxjs';
-import { map } from 'rxjs/operators';
 import { DeepLDialogComponent } from '../_dialogs/deep-ldialog/deep-ldialog.component';
 import { MatDialog } from '@angular/material/dialog';
 
@@ -51,8 +49,7 @@ export class WriteCommentComponent implements OnInit {
               public eventService: EventService,
               public languagetoolService: LanguagetoolService,
               private deeplService: DeepLService,
-              private dialog: MatDialog,
-              public deepl: DeepLService) {
+              private dialog: MatDialog) {
     this.languageService.langEmitter.subscribe(lang => {
       this.translateService.use(lang);
     });
@@ -84,22 +81,6 @@ export class WriteCommentComponent implements OnInit {
     return true;
   }
 
-  private static encodeHTML(str: string): string {
-    return str.replace(/&/g, '&amp;')
-      .replace(/</g, '&lt;')
-      .replace(/>/g, '&gt;')
-      .replace(/"/g, '&quot;')
-      .replace(/'/g, '&apos;');
-  }
-
-  private static decodeHTML(str: string): string {
-    return str.replace(/&apos;/g, '\'')
-      .replace(/&quot;/g, '"')
-      .replace(/&gt;/g, '>')
-      .replace(/&lt;/g, '<')
-      .replace(/&amp;/g, '&');
-  }
-
   ngOnInit(): void {
     this.translateService.use(localStorage.getItem('currentLang'));
     if (this.isCommentAnswer) {
@@ -183,56 +164,43 @@ export class WriteCommentComponent implements OnInit {
                           result: LanguagetoolResult,
                           onClose: (data: string, text: string, view: ViewCommentDataComponent) => void) {
     let target = TargetLang.EN_US;
-    if (result.language.detectedLanguage.code.toUpperCase().startsWith(SourceLang.EN)) {
+    const code = result.language.detectedLanguage.code.toUpperCase().split('-')[0];
+    const source = code in SourceLang ? SourceLang[code] : null;
+    if (code.startsWith(SourceLang.EN)) {
       target = TargetLang.DE;
     }
-    this.generateDeeplDelta(body, target).subscribe(([improvedBody, improvedText]) => {
-      this.isSpellchecking = false;
-      if (improvedText.replace(/\s+/g, '') === text.replace(/\s+/g, '')) {
-        onClose(body, text, this.commentData);
-        return;
-      }
-      this.dialog.open(DeepLDialogComponent, {
-        width: '900px',
-        maxWidth: '100%',
-        data: {
-          body,
-          text,
-          improvedBody,
-          improvedText,
-          maxTextCharacters: this.maxTextCharacters,
-          maxDataCharacters: this.maxDataCharacters,
-          isModerator: this.isModerator,
-          result,
-          onClose
-        }
-      }).afterClosed().subscribe(() => this.buildCreateCommentActionCallback()());
-    }, (_) => {
-      this.isSpellchecking = false;
-      onClose(body, text, this.commentData);
-    });
-  }
-
-  private generateDeeplDelta(body: string, targetLang: TargetLang): Observable<[string, string]> {
-    const delta = ViewCommentDataComponent.getDeltaFromData(body);
-    const xml = delta.ops.reduce((acc, e, i) => {
-      if (typeof e['insert'] === 'string' && e['insert'].trim().length) {
-        acc += '<x i="' + i + '">' + WriteCommentComponent.encodeHTML(e['insert']) + '</x>';
-        e['insert'] = '';
-      }
-      return acc;
-    }, '');
-    return this.deeplService.improveTextStyle(xml, targetLang).pipe(
-      map(str => {
-        const regex = /<x i="(\d+)">([^<]+)<\/x>/gm;
-        let m;
-        while ((m = regex.exec(str)) !== null) {
-          delta.ops[+m[1]]['insert'] += WriteCommentComponent.decodeHTML(m[2]);
+    DeepLDialogComponent.generateDeeplDelta(this.deeplService, body, target)
+      .subscribe(([improvedBody, improvedText]) => {
+        this.isSpellchecking = false;
+        if (improvedText.replace(/\s+/g, '') === text.replace(/\s+/g, '')) {
+          onClose(body, text, this.commentData);
+          return;
         }
-        const text = delta.ops.reduce((acc, el) => acc + (typeof el['insert'] === 'string' ? el['insert'] : ''), '');
-        return [ViewCommentDataComponent.getDataFromDelta(delta), text];
-      })
-    );
+        this.dialog.open(DeepLDialogComponent, {
+          width: '900px',
+          maxWidth: '100%',
+          data: {
+            body,
+            text,
+            improvedBody,
+            improvedText,
+            maxTextCharacters: this.maxTextCharacters,
+            maxDataCharacters: this.maxDataCharacters,
+            isModerator: this.isModerator,
+            result,
+            onClose,
+            target: DeepLService.transformSourceToTarget(source),
+            usedTarget: target
+          }
+        }).afterClosed().subscribe((val) => {
+          if (val) {
+            this.buildCreateCommentActionCallback()();
+          }
+        });
+      }, (_) => {
+        this.isSpellchecking = false;
+        onClose(body, text, this.commentData);
+      });
   }
 
 }
diff --git a/src/app/directives/joyride-template.directive.ts b/src/app/directives/joyride-template.directive.ts
index 78b18a019cc10ce6d24ddeff70a8ae003d94af00..63507799fa8f915279d52ae69ce8b3b477c87ed5 100644
--- a/src/app/directives/joyride-template.directive.ts
+++ b/src/app/directives/joyride-template.directive.ts
@@ -1,7 +1,6 @@
 import {
   ComponentFactoryResolver,
   Directive,
-  Input,
   OnInit,
   ViewContainerRef
 } from '@angular/core';
diff --git a/src/app/services/http/deep-l.service.ts b/src/app/services/http/deep-l.service.ts
index 1462c9f5349895432b7b4b14180b5f0fd814f2e1..499c71f22726463fa3735f9ea040cd6dfcba1168 100644
--- a/src/app/services/http/deep-l.service.ts
+++ b/src/app/services/http/deep-l.service.ts
@@ -4,7 +4,6 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { Observable } from 'rxjs';
 import { catchError, map, tap, timeout } from 'rxjs/operators';
 import { flatMap } from 'rxjs/internal/operators';
-import { LanguagetoolService } from './languagetool.service';
 
 const httpOptions = {
   // eslint-disable-next-line @typescript-eslint/naming-convention
@@ -75,6 +74,12 @@ export enum TargetLang {
   ZH = 'ZH'
 }
 
+export enum FormalityType {
+  default = '',
+  less = 'less',
+  more = 'more'
+}
+
 @Injectable({
   providedIn: 'root'
 })
@@ -112,22 +117,23 @@ export class DeepLService extends BaseHttpService {
     }
   }
 
-  improveTextStyle(text: string, temTargetLang: TargetLang): Observable<string> {
-    return this.makeXMLTranslateRequest(text, temTargetLang).pipe(
+  improveTextStyle(text: string, temTargetLang: TargetLang, formality = FormalityType.default): Observable<string> {
+    return this.makeXMLTranslateRequest(text, temTargetLang, formality).pipe(
       flatMap(result =>
         this.makeXMLTranslateRequest(
           result.translations[0].text,
-          DeepLService.transformSourceToTarget(result.translations[0].detected_source_language)
+          DeepLService.transformSourceToTarget(result.translations[0].detected_source_language),
+          formality
         )),
       map(result => result.translations[0].text)
     );
   }
 
-  private makeXMLTranslateRequest(text: string, targetLang: TargetLang): Observable<DeepLResult> {
+  private makeXMLTranslateRequest(text: string, targetLang: TargetLang, formality: FormalityType): Observable<DeepLResult> {
     const url = '/deepl/translate';
-    const formality = DeepLService.supportsFormality(targetLang) ? '&formality=less' : '';
+    const tagFormality = DeepLService.supportsFormality(targetLang) && formality !== FormalityType.default ? '&formality=' + formality : '';
     const additional = '?target_lang=' + encodeURIComponent(targetLang) +
-      '&tag_handling=xml' + formality +
+      '&tag_handling=xml' + tagFormality +
       '&text=' + encodeURIComponent(text);
     return this.http.get<string>(url + additional, httpOptions)
       .pipe(
diff --git a/src/app/services/util/tag-cloud-data.service.ts b/src/app/services/util/tag-cloud-data.service.ts
index 477d1240125b504f45fbfce400634b05ee5d5919..f0832a5d0d1fbe4c7e28115e1184e9b8f90896cd 100644
--- a/src/app/services/util/tag-cloud-data.service.ts
+++ b/src/app/services/util/tag-cloud-data.service.ts
@@ -23,6 +23,9 @@ export interface TagCloudDataTagEntry {
   categories: Set<string>;
   dependencies: Set<string>;
   comments: Comment[];
+  generatedByQuestionerCount: number;
+  taggedCommentsCount: number;
+  answeredCommentsCount: number;
 }
 
 export interface TagCloudMetaData {
@@ -99,43 +102,50 @@ export class TagCloudDataService {
     const data: TagCloudData = new Map<string, TagCloudDataTagEntry>();
     const users = new Set<number>();
     for (const comment of comments) {
-      TopicCloudAdminService.approveKeywordsOfComment(comment, adminData, (keyword: SpacyKeyword) => {
-        let current: TagCloudDataTagEntry = data.get(keyword.lemma);
-        const commentDate = new Date(comment.timestamp);
-        if (current === undefined) {
-          current = {
-            cachedVoteCount: 0,
-            cachedUpVotes: 0,
-            cachedDownVotes: 0,
-            comments: [],
-            weight: 0,
-            adjustedWeight: 0,
-            distinctUsers: new Set<number>(),
-            categories: new Set<string>(),
-            dependencies: new Set<string>([...keyword.dep]),
-            firstTimeStamp: commentDate,
-            lastTimeStamp: commentDate
-          };
-          data.set(keyword.lemma, current);
-        }
-        keyword.dep.forEach(dependency => current.dependencies.add(dependency));
-        current.cachedVoteCount += comment.score;
-        current.cachedUpVotes += comment.upvotes;
-        current.cachedDownVotes += comment.downvotes;
-        current.distinctUsers.add(comment.userNumber);
-        if (comment.tag) {
-          current.categories.add(comment.tag);
-        }
-        // @ts-ignore
-        if (current.firstTimeStamp - commentDate > 0) {
-          current.firstTimeStamp = commentDate;
-        }
-        // @ts-ignore
-        if (current.lastTimeStamp - commentDate < 0) {
-          current.lastTimeStamp = commentDate;
-        }
-        current.comments.push(comment);
-      });
+      TopicCloudAdminService.approveKeywordsOfComment(comment, adminData,
+        (keyword: SpacyKeyword, isFromQuestioner: boolean) => {
+          let current: TagCloudDataTagEntry = data.get(keyword.lemma);
+          const commentDate = new Date(comment.timestamp);
+          if (current === undefined) {
+            current = {
+              cachedVoteCount: 0,
+              cachedUpVotes: 0,
+              cachedDownVotes: 0,
+              comments: [],
+              weight: 0,
+              adjustedWeight: 0,
+              distinctUsers: new Set<number>(),
+              categories: new Set<string>(),
+              dependencies: new Set<string>([...keyword.dep]),
+              firstTimeStamp: commentDate,
+              lastTimeStamp: commentDate,
+              generatedByQuestionerCount: 0,
+              taggedCommentsCount: 0,
+              answeredCommentsCount: 0
+            };
+            data.set(keyword.lemma, current);
+          }
+          keyword.dep.forEach(dependency => current.dependencies.add(dependency));
+          current.cachedVoteCount += comment.score;
+          current.cachedUpVotes += comment.upvotes;
+          current.cachedDownVotes += comment.downvotes;
+          current.distinctUsers.add(comment.userNumber);
+          current.generatedByQuestionerCount += +isFromQuestioner;
+          current.taggedCommentsCount += +!!comment.tag;
+          current.answeredCommentsCount += +!!comment.answer;
+          if (comment.tag) {
+            current.categories.add(comment.tag);
+          }
+          // @ts-ignore
+          if (current.firstTimeStamp - commentDate > 0) {
+            current.firstTimeStamp = commentDate;
+          }
+          // @ts-ignore
+          if (current.lastTimeStamp - commentDate < 0) {
+            current.lastTimeStamp = commentDate;
+          }
+          current.comments.push(comment);
+        });
       users.add(comment.userNumber);
     }
     return [
@@ -199,7 +209,10 @@ export class TagCloudDataService {
           distinctUsers: new Set<number>(),
           dependencies: new Set<string>(),
           firstTimeStamp: new Date(),
-          lastTimeStamp: new Date()
+          lastTimeStamp: new Date(),
+          generatedByQuestionerCount: 0,
+          taggedCommentsCount: 0,
+          answeredCommentsCount: 0
         });
       }
     });
@@ -317,13 +330,19 @@ export class TagCloudDataService {
   }
 
   private calculateWeight(tagData: TagCloudDataTagEntry): number {
+    const value = Math.max(tagData.cachedVoteCount, 0);
+    const additional = (tagData.distinctUsers.size - 1) * 0.5 +
+      tagData.comments.reduce((acc, comment) => acc + +comment.createdFromLecturer, 0) +
+      tagData.generatedByQuestionerCount +
+      tagData.taggedCommentsCount +
+      tagData.answeredCommentsCount;
     switch (this._calcWeightType) {
       case TagCloudCalcWeightType.byVotes:
-        return tagData.cachedVoteCount;
+        return value + additional;
       case TagCloudCalcWeightType.byLengthAndVotes:
-        return tagData.cachedVoteCount / 10.0 + tagData.comments.length;
+        return value / 10.0 + tagData.comments.length + additional;
       default:
-        return tagData.comments.length;
+        return tagData.comments.length + additional;
     }
   }
 
diff --git a/src/app/services/util/topic-cloud-admin.service.ts b/src/app/services/util/topic-cloud-admin.service.ts
index ab6ec2b2fa517b53da2d357b7879fa7e157554bf..741de7eb7cbf14d002d714da5dea98c6219dda41 100644
--- a/src/app/services/util/topic-cloud-admin.service.ts
+++ b/src/app/services/util/topic-cloud-admin.service.ts
@@ -52,11 +52,16 @@ export class TopicCloudAdminService {
     room.tagCloudSettings = JSON.stringify(settings);
   }
 
-  static approveKeywordsOfComment(comment: Comment, config: TopicCloudAdminData, keywordFunc: (SpacyKeyword) => void) {
+  static approveKeywordsOfComment(comment: Comment, config: TopicCloudAdminData, keywordFunc: (SpacyKeyword, boolean) => void) {
     let source = comment.keywordsFromQuestioner;
+    let isFromQuestioner = true;
     if (config.keywordORfulltext === KeywordOrFulltext.both) {
-      source = !source || !source.length ? comment.keywordsFromSpacy : source;
+      if (!source || !source.length) {
+        source = comment.keywordsFromSpacy;
+        isFromQuestioner = false;
+      }
     } else if (config.keywordORfulltext === KeywordOrFulltext.fulltext) {
+      isFromQuestioner = false;
       source = comment.keywordsFromSpacy;
     }
     if (!source) {
@@ -76,7 +81,7 @@ export class TopicCloudAdminService {
         }
       }
       if (!isProfanity) {
-        keywordFunc(keyword);
+        keywordFunc(keyword, isFromQuestioner);
       }
     }
   }
diff --git a/src/assets/i18n/creator/de.json b/src/assets/i18n/creator/de.json
index 32db47992e0fbee0f7dbb906a5d5bde0aef1a8e9..37451b2f311611931797216d63e63fb8e30b1c74 100644
--- a/src/assets/i18n/creator/de.json
+++ b/src/assets/i18n/creator/de.json
@@ -242,6 +242,13 @@
     "option-normal": "Deine Eingabe:",
     "option-improved": "KI-Vorschlag:"
   },
+  "deepl-formality-select": {
+    "error": "Text konnte nicht geupdatet werden.",
+    "name": "Formalität",
+    "default": "Automatisch",
+    "less": "Informal",
+    "more": "Formal"
+  },
   "explanation": {
     "label": "Warum?",
     "close": "Schließen",
diff --git a/src/assets/i18n/creator/en.json b/src/assets/i18n/creator/en.json
index dd1d0b93855914e5a8adeae2d812d9b10bdb9f90..191697323754111fd46da8b653949ddc6b18d944 100644
--- a/src/assets/i18n/creator/en.json
+++ b/src/assets/i18n/creator/en.json
@@ -243,6 +243,13 @@
     "option-normal": "Your input:",
     "option-improved": "AI suggestion:"
   },
+  "deepl-formality-select": {
+    "error": "Could not update Text.",
+    "name": "Formality",
+    "default": "Automatically",
+    "less": "Informally",
+    "more": "Formally"
+  },
   "explanation": {
     "label": "Explanation",
     "close": "Close",
diff --git a/src/assets/i18n/participant/de.json b/src/assets/i18n/participant/de.json
index e11cd3b7b8c078001112ad6e8ca6c8b6b482125e..0519cea628e21cee7a48269dae3aa15dbd6b9482 100644
--- a/src/assets/i18n/participant/de.json
+++ b/src/assets/i18n/participant/de.json
@@ -170,6 +170,13 @@
     "option-normal": "Deine Eingabe:",
     "option-improved": "KI-Vorschlag:"
   },
+  "deepl-formality-select": {
+    "error": "Text konnte nicht geupdatet werden.",
+    "name": "Formalität",
+    "default": "Automatisch",
+    "less": "Informal",
+    "more": "Formal"
+  },
   "explanation": {
     "label": "Warum?",
     "close": "Schließen",
@@ -285,7 +292,7 @@
     "demo-data-topic": "Thema %d",
     "overview-question-topic-tooltip": "Anzahl Fragen mit diesem Thema",
     "overview-questioners-topic-tooltip": "Anzahl Fragensteller*innen mit diesem Thema",
-    "period-since-first-comment":"Zeitraum seit der ersten Frage",
+    "period-since-first-comment": "Zeitraum seit der ersten Frage",
     "upvote-topic": "Up-Votes für dieses Thema",
     "downvote-topic": "Down-Votes für dieses Thema",
     "blacklist-topic": "Thema auf die »Blacklist« setzen",
@@ -417,12 +424,12 @@
     "highestWeight-tooltip": "x Themen mit der höchsten Gewichtung anzeigen",
     "rotate-weight": "Themen dieser Häufigkeitsgruppe um x Grad drehen",
     "rotate-weight-tooltip": "Themen dieser Häufigkeitsgruppe um x Grad drehen",
-    "font":"Schrift",
+    "font": "Schrift",
     "reset-btn": "Auf Standardwerte setzen",
     "font-family-tooltip": "Schrift auswählen …",
     "bold-notation-tooltip": "Schrift fett setzen",
-    "font-style-bold" : "Fette Schrift",
-    "font-family":"Schriftart",
+    "font-style-bold": "Fette Schrift",
+    "font-family": "Schriftart",
     "manual-weight-number": "Anzahl Themen beschränken",
     "manual-weight-number-tooltip": "Anzahl Themen der Häufigkeitsgruppe",
     "manual-weight-number-note": "Begrenzt die Anzahl Themen einer Häufigkeitsgruppe auf den eingestellten Wert"
diff --git a/src/assets/i18n/participant/en.json b/src/assets/i18n/participant/en.json
index 4cb91c15a5418c830290019748062dc332a3e49f..abbee0a6f8f869a5b53609dd7fb3ee8e7f24f5ca 100644
--- a/src/assets/i18n/participant/en.json
+++ b/src/assets/i18n/participant/en.json
@@ -179,6 +179,13 @@
     "option-normal": "Your input:",
     "option-improved": "AI suggestion:"
   },
+  "deepl-formality-select": {
+    "error": "Could not update Text.",
+    "name": "Formality",
+    "default": "Automatically",
+    "less": "Informally",
+    "more": "Formally"
+  },
   "explanation": {
     "label": "Explanation",
     "close": "Close",