コード例 #1
0
        public DataMatrix ChecklistReport(int taxonID, string criteriaDisplayText, ChecklistReportExtent extent, bool availableNames, bool literatureNames, ChecklistReportRankDepth?depth, bool userDefinedOrder, bool verifiedOnly, List <TaxonRankName> selectedRanks)
        {
            var b = new RTFReportBuilder();

            var data = GetChecklistData(taxonID, 0, extent == ChecklistReportExtent.FullHierarchy, userDefinedOrder, verifiedOnly, selectedRanks);

            // Process the list, generating the RTF...
            // Create the Header inforrmation
            b.AppendFullHeader();
            // Create the title information
            b.Append(@"\pard\fs36\b Taxon Checklist Report\b0\pard\par\fs22 ").Append(criteriaDisplayText).Append(@"\pard\par\fs16 Generated: ");
            b.AppendCurrentDate().Par().Par();

            int i = 0;

            foreach (ChecklistData item in data)
            {
                ++i;
                if (!availableNames && item.AvailableName || !literatureNames && item.LiteratureName)
                {
                    // ignore this one
                }
                else
                {
                    b.Append(@"\par\pard\fs20\li{0} {1}", item.IndentLevel * 300, FormatChecklistRow(item, i, depth));
                }
            }

            b.Append("}");

            return(b.GetAsMatrix());
        }
コード例 #2
0
ファイル: MaterialService.cs プロジェクト: kehh/biolink
        public DataMatrix GetTaxaForSites(bool includeLocations, string itemType, int itemID, int biotaID, string criteriaText)
        {
            var taxonService = new TaxaService(User);
            var rtf = new RTFReportBuilder();

            // Create the Header inforrmation
            rtf.AppendFullHeader();

            // Create the title information
            rtf.Append(@"\pard\fs36\b Taxa for Site/Region Report\b0\pard\par\fs24 ").Append(criteriaText);
            rtf.Append(@"\pard\par\fs24 Produced: ").AppendCurrentDate();

            // extract the parentage string from the database.
            // Loop through the recordset and build the report output.
            int lngLastBiotaID = -1;
            int lngLastRegionID = -1;
            int lngLastSiteID = -1;
            string strOrderRank = "";
            string strFamilyRank = "";

            StoredProcReaderForEach("spReportTaxaForSites", (reader) => {
                // If there is a change in taxa, print the header.
                int currentBiotaID = (int) reader["BiotaID"];
                if (lngLastBiotaID != currentBiotaID) {
                    lngLastBiotaID = currentBiotaID;
                    lngLastRegionID = -1;
                    lngLastSiteID = -1;
                    rtf.Par().Par().Append(@"\pard\sb20\fs28\b ");
                    rtf.Append(AsString(reader["BiotaFullName"])).Append(@"\b0");

                    // extract the family and order
                    strOrderRank = taxonService.GetBiotaRankElemType(currentBiotaID, "O");
                    strFamilyRank = taxonService.GetBiotaRankElemType(currentBiotaID, "F");

                    if (!string.IsNullOrWhiteSpace(strOrderRank) && string.IsNullOrWhiteSpace(strFamilyRank)) {
                        rtf.Append("  [").Append(strOrderRank).Append("]");
                    } else if ((!string.IsNullOrWhiteSpace(strOrderRank) || (!string.IsNullOrWhiteSpace(strFamilyRank)))) {
                        rtf.Append("  [").Append(strOrderRank).Append(": ").Append(strFamilyRank).Append("]");
                    }
                }

                if (includeLocations) {
                    // Add the region group
                    int currentRegionID = (int) reader["RegionID"];
                    if (lngLastRegionID != currentRegionID) {
                        // Add the region
                        lngLastRegionID = currentRegionID;
                        rtf.Par().Append(@"\pard\sb10\fs20\li600 ");
                        rtf.Append(AsString(reader["FullRegion"]));
                    }

                    int currentSiteID = (int) reader["SiteID"];

                    if (lngLastSiteID != currentSiteID) {
                        lngLastSiteID = currentSiteID;
                        // Add the Site
                        rtf.Par().Append(@"\pard\sb10\fs20\li1200 ");
                        // Add the locality
                        int localType = (byte) reader["LocalType"];
                        switch (localType) {
                            case 0:
                                rtf.Append(AsString(reader["Local"]));
                                break;
                            case 1:
                                rtf.Append(AsString(reader["DistanceFromPlace"])).Append(" ");
                                rtf.Append(AsString(reader["DirFromPlace"])).Append(" of ").Append(AsString(reader["Local"]));
                                break;
                            default:
                                rtf.Append(AsString(reader["Local"]));
                                break;
                        }

                       // Add the long and lat.
                        int areaType = (int) reader.Get<byte>("AreaType", (byte) 0);

                        double? lat = reader.Get<double?>("Lat");
                        double? lon = reader.Get<double?>("Long");

                        double? lat2 = reader.Get<double?>("Lat2");
                        double? lon2 = reader.Get<double?>("Long2");

                        switch (areaType) {
                            case 1:   // Point

                                if (!lat.HasValue || !lon.HasValue) {
                                    rtf.Append("; No position data");
                                } else {
                                    rtf.Append("; {0}, {1}", GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude), GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude));
                                }
                                break;
                            case 2:  // Box
                                if (!lat.HasValue || !lon.HasValue || !lat2.HasValue || !lon2.HasValue) {
                                    rtf.Append("; No position data");
                                } else {
                                    rtf.Append("; Box: {0}, {1}; {2}, {3}",
                                        GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude),
                                        GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude),
                                        GeoUtils.DecDegToDMS(lat2.Value, CoordinateType.Latitude),
                                        GeoUtils.DecDegToDMS(lon2.Value, CoordinateType.Longitude));
                                }
                                break;
                            case 3: // Line
                                if (!lat.HasValue || !lon.HasValue || !lat2.HasValue || !lon2.HasValue) {
                                    rtf.Append("; No position data");
                                } else {
                                    rtf.Append("; Line: {0}, {1}; {2}, {3}",
                                        GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude),
                                        GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude),
                                        GeoUtils.DecDegToDMS(lat2.Value, CoordinateType.Latitude),
                                        GeoUtils.DecDegToDMS(lon2.Value, CoordinateType.Longitude));
                                }
                                break;
                            default:
                                // ignore
                                break;
                        }

                    }
                }

            }, _P("vchrItemType", itemType), _P("intItemID", itemID), _P("intBiotaID", biotaID));

            rtf.Append(" }");

            return rtf.GetAsMatrix();
        }
コード例 #3
0
        public DataMatrix TaxaForSites(int siteOrRegionID, int taxonID, string itemType, string criteriaDisplayText, bool includeLocations)
        {
            var rtf = new RTFReportBuilder();

            rtf.AppendFullHeader();
            rtf.ReportHeading("Taxa for Site/Region Report");
            rtf.Append(criteriaDisplayText);
            rtf.Append(@"\pard\par\fs24 Produced: ").AppendCurrentDate();

            int lngLastBiotaID  = -1;
            int lngLastRegionID = -1;
            int lngLastSiteID   = -1;

            bool hasResults = false;

            StoredProcReaderForEach("spReportTaxaForSites", (reader) => {
                hasResults = true;
                // If there is a change in taxa, print the header.
                int biotaID = (Int32)reader["BiotaID"];
                if (lngLastBiotaID != biotaID)
                {
                    lngLastBiotaID  = biotaID;
                    lngLastRegionID = -1;
                    lngLastSiteID   = -1;
                    rtf.Par().Par().Append(@"\pard\sb20\fs28\b ");
                    rtf.Append(AsString(reader["BiotaFullName"])).Append(@"\b0");
                    // extract the family and order
                    string orderRank  = GetBiotaRankElemType(lngLastBiotaID, "O");
                    string familyRank = GetBiotaRankElemType(lngLastBiotaID, "F");

                    if (!string.IsNullOrWhiteSpace(orderRank) && string.IsNullOrWhiteSpace(familyRank))
                    {
                        rtf.Append("  [").Append(orderRank).Append("]");
                    }
                    else if (!string.IsNullOrWhiteSpace(orderRank) && !string.IsNullOrWhiteSpace(familyRank))
                    {
                        rtf.Append("  [").Append(orderRank).Append(": ").Append(familyRank).Append("]");
                    }
                }

                if (includeLocations)
                {
                    // Add the region group
                    int regionID = (Int32)reader["RegionID"];

                    if (lngLastRegionID != regionID)
                    {
                        // Add the region
                        lngLastRegionID = regionID;
                        rtf.Par().Append(@"\pard\sb10\fs20\li600\b ").Append(AsString(reader["FullRegion"])).Append(@"\b0 ");
                    }

                    int siteID = (Int32)reader["SiteID"];
                    if (lngLastSiteID != siteID)
                    {
                        lngLastSiteID = siteID;
                        // Add the Site
                        rtf.Par().Append(@"\pard\sb10\fs20\li1200 ");
                        // Add the locality
                        byte localType = (byte)reader["LocalType"];
                        switch (localType)
                        {
                        case 0:
                            rtf.Append(reader["Local"] as string);
                            break;

                        case 1:
                            rtf.Append(reader["DistanceFromPlace"]).Append(" ").Append(reader["DirFromPlace"]).Append(" of ").Append(reader["Local"]);
                            break;

                        default:
                            rtf.Append(reader["Local"] as string);
                            break;
                        }

                        // Add the long and lat.

                        byte areaType = (byte)reader["AreaType"];
                        double?lat    = reader["Lat"] as double?;
                        double?lon    = reader["Long"] as double?;
                        double?lat2   = reader["Lat2"] as double?;
                        double?lon2   = reader["Long2"] as double?;

                        if (!lat.HasValue || !lon.HasValue)
                        {
                            rtf.Append("; No position data");
                        }
                        else
                        {
                            switch (areaType)
                            {
                            case 1:
                                rtf.Append("; ");
                                rtf.Append(GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude));
                                rtf.Append(", ");
                                rtf.Append(GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude));
                                break;

                            case 2:
                                rtf.Append("; Box: ");
                                rtf.Append(GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude));
                                rtf.Append(", ");
                                rtf.Append(GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude));
                                rtf.Append("; ");
                                if (!lat2.HasValue || !lon2.HasValue)
                                {
                                    rtf.Append("; No position data for second coordinate");
                                }
                                else
                                {
                                    rtf.Append(GeoUtils.DecDegToDMS(lat2.Value, CoordinateType.Latitude));
                                    rtf.Append(", ");
                                    rtf.Append(GeoUtils.DecDegToDMS(lon2.Value, CoordinateType.Longitude));
                                }
                                break;

                            case 3:
                                rtf.Append("; Line: ");
                                rtf.Append(GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude));
                                rtf.Append(", ");
                                rtf.Append(GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude));
                                rtf.Append("; ");
                                if (!lat2.HasValue || !lon2.HasValue)
                                {
                                    rtf.Append("; No position data for second coordinate");
                                }
                                else
                                {
                                    rtf.Append(GeoUtils.DecDegToDMS(lat2.Value, CoordinateType.Latitude));
                                    rtf.Append(", ");
                                    rtf.Append(GeoUtils.DecDegToDMS(lon2.Value, CoordinateType.Longitude));
                                }

                                break;

                            default:
                                break;
                            }
                        }
                    }
                }
            }, _P("vchrItemType", itemType), _P("intItemID", siteOrRegionID), _P("intBiotaID", taxonID));

            if (!hasResults)
            {
                rtf.Par().Par().Append("No results.");
            }


            rtf.Append("}");

            return(rtf.GetAsMatrix());
        }
コード例 #4
0
        public DataMatrix TaxaForDistributionRegionReport(int regionId, int taxonId)
        {
            var region = new SupportService(User).GetDistributionRegion(regionId);

            if (region == null)
            {
                throw new Exception("Could not retrieve region: " + regionId);
            }

            Taxon taxon = null;

            if (taxonId > 0)
            {
                taxon = GetTaxon(taxonId);
                if (taxon == null)
                {
                    throw new Exception("Could not retrieve taxon: " + taxonId);
                }
            }

            var rtf = new RTFReportBuilder();

            rtf.AppendFullHeader();
            rtf.ReportHeading("Taxa for Distribution Region Report");
            rtf.Append("Region: {0}", region.DistRegionName);
            if (taxon != null)
            {
                rtf.Append(" Taxon: {0}", taxon.TaxaFullName);
            }

            rtf.Append(@"\pard\par\fs24 Produced: ").AppendCurrentDate();

            int rowCount     = 0;
            int lastRegionId = -1;
            int lastTaxonId  = -1;

            StoredProcReaderForEach("spReportTaxaForDistRegion", (reader) => {
                rowCount++;
                int currentRegionId = (int)reader["DistRegionID"];
                if (lastRegionId != currentRegionId)
                {
                    lastRegionId   = currentRegionId;
                    lastTaxonId    = -1;
                    var regionName = reader["DistRegion"] as string;
                    regionName     = regionName.Replace('\\', ':');
                    rtf.Par().Par().Append(@"\pard\sb20\fs24\b ").Append(regionName).Append(@"\b0 ");
                }

                var currentTaxonId = (int)reader["BiotaID"];
                if (lastTaxonId != currentTaxonId)
                {
                    lastTaxonId = currentTaxonId;
                    rtf.Par().Append(@"\pard\sb10\fs20\li600 ").Append(reader["Biota"].ToString());
                }
            }, _P("intDistributionRegionID", regionId), _P("intBiotaID", taxonId));

            if (rowCount == 0)
            {
                rtf.Par().Append("No results...");
            }

            rtf.Append(" }");

            return(rtf.GetAsMatrix());
        }
コード例 #5
0
ファイル: TaxaService.cs プロジェクト: kehh/biolink
        public DataMatrix ChecklistReport(int taxonID, string criteriaDisplayText, ChecklistReportExtent extent, bool availableNames, bool literatureNames, ChecklistReportRankDepth? depth, bool userDefinedOrder, bool verifiedOnly, List<TaxonRankName> selectedRanks)
        {
            var b = new RTFReportBuilder();

            var data = GetChecklistData(taxonID, 0, extent == ChecklistReportExtent.FullHierarchy, userDefinedOrder, verifiedOnly, selectedRanks);

            // Process the list, generating the RTF...
            // Create the Header inforrmation
            b.AppendFullHeader();
            // Create the title information
            b.Append(@"\pard\fs36\b Taxon Checklist Report\b0\pard\par\fs22 ").Append(criteriaDisplayText).Append(@"\pard\par\fs16 Generated: ");
            b.AppendCurrentDate().Par().Par();

            int i = 0;
            foreach (ChecklistData item in data) {
                ++i;
                if (!availableNames && item.AvailableName || !literatureNames && item.LiteratureName) {
                    // ignore this one
                } else {
                    b.Append(@"\par\pard\fs20\li{0} {1}", item.IndentLevel * 300, FormatChecklistRow(item, i, depth));
                }
            }

            b.Append("}");

            return b.GetAsMatrix();
        }
コード例 #6
0
ファイル: TaxaService.cs プロジェクト: kehh/biolink
        public DataMatrix TaxaForSites(int siteOrRegionID, int taxonID, string itemType, string criteriaDisplayText, bool includeLocations)
        {
            var rtf = new RTFReportBuilder();
            rtf.AppendFullHeader();
            rtf.ReportHeading("Taxa for Site/Region Report");
            rtf.Append(criteriaDisplayText);
            rtf.Append(@"\pard\par\fs24 Produced: ").AppendCurrentDate();

            int lngLastBiotaID = -1;
            int lngLastRegionID = -1;
            int lngLastSiteID = -1;

            bool hasResults = false;
            StoredProcReaderForEach("spReportTaxaForSites", (reader) => {
                hasResults = true;
                // If there is a change in taxa, print the header.
                int biotaID = (Int32) reader["BiotaID"];
                if (lngLastBiotaID != biotaID) {
                    lngLastBiotaID = biotaID;
                    lngLastRegionID = -1;
                    lngLastSiteID = -1;
                    rtf.Par().Par().Append(@"\pard\sb20\fs28\b ");
                    rtf.Append(AsString(reader["BiotaFullName"])).Append(@"\b0");
                    // extract the family and order
                    string orderRank = GetBiotaRankElemType(lngLastBiotaID, "O");
                    string familyRank = GetBiotaRankElemType(lngLastBiotaID, "F");

                    if (!string.IsNullOrWhiteSpace(orderRank) && string.IsNullOrWhiteSpace(familyRank)) {
                        rtf.Append("  [").Append(orderRank).Append("]");
                    } else if (!string.IsNullOrWhiteSpace(orderRank) && !string.IsNullOrWhiteSpace(familyRank)) {
                        rtf.Append("  [").Append(orderRank).Append(": ").Append(familyRank).Append("]");
                    }
                }

                if (includeLocations) {
                    // Add the region group
                    int regionID = (Int32)reader["RegionID"];

                    if (lngLastRegionID != regionID) {
                        // Add the region
                        lngLastRegionID = regionID;
                        rtf.Par().Append(@"\pard\sb10\fs20\li600\b ").Append(AsString(reader["FullRegion"])).Append(@"\b0 ");
                    }

                    int siteID = (Int32)reader["SiteID"];
                    if (lngLastSiteID != siteID) {
                        lngLastSiteID = siteID;
                        // Add the Site
                        rtf.Par().Append(@"\pard\sb10\fs20\li1200 ");
                        // Add the locality
                        byte localType = (byte) reader["LocalType"];
                        switch (localType) {
                            case 0:
                                rtf.Append(reader["Local"] as string);
                                break;
                            case 1:
                                rtf.Append(reader["DistanceFromPlace"]).Append(" ").Append(reader["DirFromPlace"]).Append(" of ").Append(reader["Local"]);
                                break;
                            default:
                                rtf.Append(reader["Local"] as string);
                                break;
                        }

                        // Add the long and lat.

                        byte areaType = (byte) reader["AreaType"];
                        double? lat = reader["Lat"] as double?;
                        double? lon = reader["Long"] as double?;
                        double? lat2 = reader["Lat2"] as double?;
                        double? lon2 = reader["Long2"] as double?;

                        if (!lat.HasValue || !lon.HasValue) {
                            rtf.Append("; No position data");
                        } else {
                            switch (areaType) {
                                case 1:
                                    rtf.Append("; ");
                                    rtf.Append(GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude));
                                    rtf.Append(", ");
                                    rtf.Append(GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude));
                                    break;
                                case 2:
                                    rtf.Append("; Box: ");
                                    rtf.Append(GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude));
                                    rtf.Append(", ");
                                    rtf.Append(GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude));
                                    rtf.Append("; ");
                                    if (!lat2.HasValue || !lon2.HasValue) {
                                        rtf.Append("; No position data for second coordinate");
                                    } else {
                                        rtf.Append(GeoUtils.DecDegToDMS(lat2.Value, CoordinateType.Latitude));
                                        rtf.Append(", ");
                                        rtf.Append(GeoUtils.DecDegToDMS(lon2.Value, CoordinateType.Longitude));
                                    }
                                    break;
                                case 3:
                                    rtf.Append("; Line: ");
                                    rtf.Append(GeoUtils.DecDegToDMS(lat.Value, CoordinateType.Latitude));
                                    rtf.Append(", ");
                                    rtf.Append(GeoUtils.DecDegToDMS(lon.Value, CoordinateType.Longitude));
                                    rtf.Append("; ");
                                    if (!lat2.HasValue || !lon2.HasValue) {
                                        rtf.Append("; No position data for second coordinate");
                                    } else {
                                        rtf.Append(GeoUtils.DecDegToDMS(lat2.Value, CoordinateType.Latitude));
                                        rtf.Append(", ");
                                        rtf.Append(GeoUtils.DecDegToDMS(lon2.Value, CoordinateType.Longitude));
                                    }

                                    break;
                                default:
                                    break;
                            }

                        }
                    }
                }
            }, _P("vchrItemType", itemType), _P("intItemID", siteOrRegionID), _P("intBiotaID", taxonID));

            if (!hasResults) {
                rtf.Par().Par().Append("No results.");
            }

            rtf.Append("}");

            return rtf.GetAsMatrix();
        }
コード例 #7
0
ファイル: TaxaService.cs プロジェクト: kehh/biolink
        public DataMatrix TaxaForDistributionRegionReport(int regionId, int taxonId)
        {
            var region = new SupportService(User).GetDistributionRegion(regionId);
            if (region == null) {
                throw new Exception("Could not retrieve region: " + regionId);
            }

            Taxon taxon = null;
            if (taxonId > 0) {
                taxon = GetTaxon(taxonId);
                if (taxon == null) {
                    throw new Exception("Could not retrieve taxon: " + taxonId);
                }
            }

            var rtf = new RTFReportBuilder();
            rtf.AppendFullHeader();
            rtf.ReportHeading("Taxa for Distribution Region Report");
            rtf.Append("Region: {0}", region.DistRegionName);
            if (taxon != null) {
                rtf.Append(" Taxon: {0}", taxon.TaxaFullName);
            }

            rtf.Append(@"\pard\par\fs24 Produced: ").AppendCurrentDate();

            int rowCount = 0;
            int lastRegionId = -1;
            int lastTaxonId = -1;
            StoredProcReaderForEach("spReportTaxaForDistRegion", (reader) => {
                rowCount++;
                int currentRegionId = (int) reader["DistRegionID"];
                if (lastRegionId != currentRegionId) {
                    lastRegionId = currentRegionId;
                    lastTaxonId = -1;
                    var regionName = reader["DistRegion"] as string;
                    regionName = regionName.Replace('\\', ':');
                    rtf.Par().Par().Append(@"\pard\sb20\fs24\b ").Append(regionName).Append(@"\b0 ");
                }

                var currentTaxonId = (int)reader["BiotaID"];
                if (lastTaxonId != currentTaxonId) {
                    lastTaxonId = currentTaxonId;
                    rtf.Par().Append(@"\pard\sb10\fs20\li600 ").Append(reader["Biota"].ToString());
                }

            }, _P("intDistributionRegionID", regionId), _P("intBiotaID", taxonId));

            if (rowCount == 0) {
                rtf.Par().Append("No results...");
            }

            rtf.Append(" }");

            return rtf.GetAsMatrix();
        }
コード例 #8
0
ファイル: TaxonReferencesReport.cs プロジェクト: kehh/biolink
        public System.Windows.FrameworkElement ConstructView(IBioLinkReport report, DataMatrix reportData, IProgressObserver progress)
        {
            var options = (report as ReferenceLinksReport).Options;

            var viewer = new RTFReportViewer {ReportName = report.Name};
            var rtf = new RTFReportBuilder();
            rtf.AppendFullHeader();
            rtf.ReportHeading(options.BibliographyTitle);

            var idx = 1;
            var colIndex = reportData.IndexOf("RefID");

            var refIds = new List<Int32>();
            for (var i = 0; i < reportData.Rows.Count; ++i ) {
                refIds.Add(i);
            }

            int sortColumnIdx = reportData.IndexOf(options.SortColumn);
            int refTypeIndex = reportData.IndexOf("RefType");
            refIds.Sort((idx1, idx2) => {
                            // If grouping, first check the ref type
                            if (options.GroupByReferenceType) {
                                var refType1 = reportData.Rows[idx1][refTypeIndex] as String;
                                var refType2 = reportData.Rows[idx2][refTypeIndex] as String;
                                if (!refType1.Equals(refType2)) {
                                    return String.Compare(refType1, refType2, true);
                                }
                            }

                            // then by the nominated sort column
                            var objVal1 = reportData.Rows[idx1][sortColumnIdx];
                            var objVal2 = reportData.Rows[idx2][sortColumnIdx];
                            var val1 = RTFUtils.StripMarkup(objVal1 == null ? "" : objVal1.ToString());
                            var val2 = RTFUtils.StripMarkup(objVal2 == null ? "" : objVal2.ToString());

                            if (options.SortAscending) {
                                return String.Compare((String)val1, (String)val2, true);
                            } else {
                                return String.Compare((String)val2, (String)val1, true);
                            }
                        });

            var lastRefType = "";
            String[] allowedKeywords = { "b", "i", "sub", "super", "strike", "ul", "ulnone", "nosupersub" };
            foreach (var rowIdx in refIds) {
                var row = reportData.Rows[rowIdx];

                if (options.GroupByReferenceType) {
                    var refType = row["RefType"] as String;
                    if (!String.Equals(refType, lastRefType, StringComparison.CurrentCultureIgnoreCase)) {
                        rtf.Par();
                        rtf.Append(@" \pard\fs24\b\f1 ");
                        rtf.Append(refType);
                        rtf.Append(@" \b0");
                        rtf.Par();
                        lastRefType = refType;
                    }
                }

                rtf.Par();
                rtf.Append(@" \pard\fs20\f1 ");
                if (options.BibliographyIndexStyle != BibliographyIndexStyle.None) {
                    rtf.Append("[");
                    switch (options.BibliographyIndexStyle) {
                        case BibliographyIndexStyle.Number:
                            rtf.Append(idx);
                            break;
                        case BibliographyIndexStyle.RefCode:
                            rtf.Append(row["RefCode"]);
                            break;
                    }
                    rtf.Append("] ");
                }
                idx++;

                var fullRTF = RTFUtils.filter(row["FullRTF"] as string, true, false, allowedKeywords);
                rtf.Append(fullRTF);

                var bits = new List<String>();
                if (!String.IsNullOrWhiteSpace(row["LinkPage"] as String)) {
                    bits.Add(String.Format("page {0}", row["LinkPage"] as String));
                }

                if (options.IncludeQualification) {
                    var qual = row["LinkQualificationRTF"] as string;
                    if (!String.IsNullOrEmpty(qual)  ) {
                        bits.Add(RTFUtils.filter(qual, true, true, allowedKeywords).Trim());
                    }
                }

                if (bits.Count > 0) {
                    rtf.Append(" (").Append(bits.Join("; ").Trim()).Append(")");
                }

                rtf.Par();
            }

            Console.WriteLine(rtf.RTF);

            viewer.rtf.Rtf = rtf.RTF;

            return viewer;
        }