diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.json b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.json
new file mode 100644
index 00000000..c6214e1e
--- /dev/null
+++ b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.json
@@ -0,0 +1,101 @@
+[
+ {
+ "@type": "FlightReservation",
+ "reservationFor": {
+ "@type": "Flight",
+ "airline": {
+ "@type": "Airline",
+ "iataCode": "IB",
+ "name": "Iberia Express"
+ },
+ "arrivalAirport": {
+ "@type": "Airport",
+ "iataCode": "MAD",
+ "name": "Madrid"
+ },
+ "arrivalTime": "2018-07-20T15:35:00",
+ "departureAirport": {
+ "@type": "Airport",
+ "iataCode": "TXL",
+ "name": "Berlin"
+ },
+ "departureTime": "2018-07-20T12:25:00",
+ "flightNumber": "3677"
+ },
+ "reservationNumber": "XXX007"
+ },
+ {
+ "@type": "FlightReservation",
+ "reservationFor": {
+ "@type": "Flight",
+ "airline": {
+ "@type": "Airline",
+ "iataCode": "IB",
+ "name": "Iberia Regional Air Nostrum"
+ },
+ "arrivalAirport": {
+ "@type": "Airport",
+ "iataCode": "LEI",
+ "name": "Almeria"
+ },
+ "arrivalTime": "2018-07-20T19:00:00",
+ "departureAirport": {
+ "@type": "Airport",
+ "iataCode": "MAD",
+ "name": "Madrid"
+ },
+ "departureTime": "2018-07-20T17:50:00",
+ "flightNumber": "8588"
+ },
+ "reservationNumber": "XXX007"
+ },
+ {
+ "@type": "FlightReservation",
+ "reservationFor": {
+ "@type": "Flight",
+ "airline": {
+ "@type": "Airline",
+ "iataCode": "IB",
+ "name": "Iberia Regional Air Nostrum"
+ },
+ "arrivalAirport": {
+ "@type": "Airport",
+ "iataCode": "MAD",
+ "name": "Madrid"
+ },
+ "arrivalTime": "2018-07-28T08:25:00",
+ "departureAirport": {
+ "@type": "Airport",
+ "iataCode": "LEI",
+ "name": "Almeria"
+ },
+ "departureTime": "2018-07-28T07:15:00",
+ "flightNumber": "8603"
+ },
+ "reservationNumber": "XXX007"
+ },
+ {
+ "@type": "FlightReservation",
+ "reservationFor": {
+ "@type": "Flight",
+ "airline": {
+ "@type": "Airline",
+ "iataCode": "IB"
+ },
+ "arrivalAirport": {
+ "@type": "Airport",
+ "iataCode": "TXL",
+ "name": "Berlin"
+ },
+ "arrivalTime": "2018-07-28T15:00:00",
+ "departureAirport": {
+ "@type": "Airport",
+ "iataCode": "MAD",
+ "name": "Madrid"
+ },
+ "departureTime": "2018-07-28T12:00:00",
+ "flightNumber": "3186"
+ },
+ "reservationNumber": "XXX007"
+ }
+]
diff --git a/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.txt b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.txt
new file mode 100644
index 00000000..63a1dfe2
--- /dev/null
+++ b/plugins/messageviewer/bodypartformatter/autotests/unstructureddata/iberia_1.txt
@@ -0,0 +1,45 @@
+ Strichcode0752371401064KRAU
+ Ihres Flugscheins in den
+ Check-In Automaten einführen.
+ Insert the barcode into the check-in
+ machines.
+Ihr E-Ticket und Reiseroutel
+Your electronic ticket and itinerary.
+Check-in erforderlich / Need to check in.
+Passagierdaten /Passenger data
+Name (Nicht übertragbar) /Name (not transferable)
+DOE, JOHN
+Ausweisdokument /Identity document Buchungsnummer /Booking code
+ XXX007
+Ticketnummer /Number
+075-1234567890
+Flugdaten /Flight data
+Ausgangspunkt/Zielort Flug Abflug Ankunft Nicht gültig Klasse - Tarif Freigepäck Flugstatus
+Origin/Destination Flight Departure Arrival Not Valid Class - Fare Baggage Status
+ Von /From IB3677 20-Jul 20-Jul Vor dem /Before F 1PC / Bestätigt
+ Berlin (TXL) 12:25 15:35 20-Jul FNNN0C Confirmed
+ Nach /To Terminal 4 Nach /After
+ Madrid (MAD) 20-Jul
+ Durchgeführt von /Operated by
+ : Iberia Express
+ Von /From IB8588 20-Jul 20-Jul Vor dem /Before F 1 Stück- Bestätigt
+ Madrid (MAD) 17:50 19:00 20-Jul FNNN0C System /Pieces Confirmed
+ Nach /To Terminal 4 Nach /After
+ Almeria (LEI) 20-Jul
+ Durchgeführt von /Operated by
+ : Iberia Regional Air Nostrum
+ Von /From IB8603 28-Jul 28-Jul Vor dem /Before H 1 Stück- Bestätigt
+ Almeria (LEI) 07:15 08:25 28-Jul HDNN0C System /Pieces Confirmed
+ Nach /To Terminal 4 Nach /After
+ Madrid (MAD) 28-Jul
+ Durchgeführt von /Operated by
+ : Iberia Regional Air Nostrum
+ Von /From IB3186 28-Jul 28-Jul Vor dem /Before H 1 Stück- Bestätigt
+ Madrid (MAD) 12:00 15:00 28-Jul HDNN0C System /Pieces Confirmed
+ Nach /To Terminal 4S Nach /After
+ Berlin (TXL) 28-Jul
+Einzelheiten zur Ticketausstellung /Ticket issue data
+Ticketnummer /Number Ausstellungsdatum /Issue date Ausgestelltvon /Issued by
+075-1234567890 05-Juni-2017 IBERIA LAE SA Operadora Unipersonal
+Büronummer /Iss. Off. Code Steuernummer /Fiscal No. Ausstellungsort /Place of issue
+12345678 A12345678 Spanien
diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/extractors.qrc b/plugins/messageviewer/bodypartformatter/semantic/extractors/extractors.qrc
index 75a35df3..21b92cf2 100644
--- a/plugins/messageviewer/bodypartformatter/semantic/extractors/extractors.qrc
+++ b/plugins/messageviewer/bodypartformatter/semantic/extractors/extractors.qrc
@@ -1,18 +1,20 @@
amadeus.json
amadeus.js
brusselsairlines.json
brusselsairlines.js
deutschebahn.json
deutschebahn.js
eurowings.json
eurowings.js
fcmtravel.json
fcmtravel.js
+ iberia.json
+ iberia.js
sncf.json
sncf.js
swiss.json
swiss.js
diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.js b/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.js
new file mode 100644
index 00000000..97462f21
--- /dev/null
+++ b/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.js
@@ -0,0 +1,82 @@
+/*
+ Copyright (c) 2017 Volker Krause
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+function parseDate(dateStr, timeStr) {
+ // the text does not contain the year at all, so guess that from Context.senderDate
+ var date = JsonLd.toDateTime(dateStr + '-' + Context.senderDate.getFullYear() + ' ' + timeStr, "dd-MMM-yyyy hh:mm", "en");
+ if (date < Context.senderDate)
+ date.setFullYear(Context.senderDate.getFullYear() + 1);
+ return date;
+}
+
+function main(text) {
+ var reservations = new Array();
+
+ var bookingRef = text.match(/Booking code\n.*([0-9A-z]{6})\n/);
+ if (!bookingRef)
+ return reservations;
+
+ var pos = bookingRef.index + bookingRef[0].length;
+ while (true) {
+ var firstLine = text.substr(pos).match(/From +([A-Z]{2})(\d{2,4}) +(\d{1,2}-\w{3}) +(\d{1,2}-\w{3}).*\n/);
+ if (!firstLine)
+ break;
+ var index = firstLine.index + firstLine[0].length;
+
+ var res = JsonLd.newObject("FlightReservation");
+ res.reservationNumber = bookingRef[1];
+ res.reservationFor = JsonLd.newObject("Flight");
+ res.reservationFor.flightNumber = firstLine[2];
+ res.reservationFor.airline = JsonLd.newObject("Airline");
+ res.reservationFor.airline.iataCode = firstLine[1];
+
+ var secondLine = text.substr(pos + index).match(/^ (\w+) \(([A-Z]{3})\) +(\d{2}:\d{2}) + (\d{2}:\d{2}) .*\n/);
+ if (!secondLine)
+ break;
+ index += secondLine.index + secondLine[0].length;
+
+ res.reservationFor.departureAirport = JsonLd.newObject("Airport");
+ res.reservationFor.departureAirport.name = secondLine[1];
+ res.reservationFor.departureAirport.iataCode = secondLine[2];
+ res.reservationFor.departureTime = parseDate(firstLine[3], secondLine[3]);
+ res.reservationFor.arrivalTime = parseDate(firstLine[4], secondLine[4]);
+
+ var fourthLine = text.substr(pos + index).match(/^.*\n (\w+) \(([A-Z]{3})\) .*\n/);
+ if (!fourthLine)
+ break;
+ index += fourthLine.index + fourthLine[0].length;
+
+ res.reservationFor.arrivalAirport = JsonLd.newObject("Airport");
+ res.reservationFor.arrivalAirport.name = fourthLine[1];
+ res.reservationFor.arrivalAirport.iataCode = fourthLine[2];
+
+ var opByLine = text.substr(pos + index).match(/^.*Operated by\n +: (.*)\n/);
+ if (opByLine) {
+ index += opByLine.index + opByLine[0].length;
+ res.reservationFor.airline.name = opByLine[1];
+ }
+
+ reservations.push(res);
+ if (index == 0)
+ break;
+ pos += index;
+ }
+
+ return reservations;
+}
diff --git a/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.json b/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.json
new file mode 100644
index 00000000..ce377c7e
--- /dev/null
+++ b/plugins/messageviewer/bodypartformatter/semantic/extractors/iberia.json
@@ -0,0 +1,6 @@
+{
+ "filter": [
+ { "header": "From", "match": "@iberia.com" }
+ ],
+ "script": "iberia.js"
+}