Changeset 192 for trunk/Forms/UFormCheck.pas
- Timestamp:
- Jul 17, 2018, 2:39:01 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Forms/UFormCheck.pas
r191 r192 51 51 procedure FindInSummary; 52 52 procedure FindInContent; 53 function AllowedSideChar(Before, After: Char): Boolean; 53 54 function ParseMeaning(Acronym, Text: string; StartIndex: Integer; 54 55 out Meaning: string; DashSeparator: Boolean = False): Boolean; 55 56 function IsUppercaseAlpha(Text: string): Boolean; 57 function IsLowercaseAlpha(Text: string): Boolean; 56 58 function IsAlpha(Text: string): Boolean; 57 59 function IsAcronym(Text: string): Boolean; 60 function IsDigit(Text: Char): Boolean; 58 61 procedure ReportDifferencies; 59 62 function WordContainsLetters(Text, Letters: string): Boolean; … … 82 85 SMissingAcronymContent = 'Warning: Document body acronym %s with meaning "%s" missing from acronym summary.'; 83 86 SMissingAcronymSummary = 'Warning: Summary acronym %s with meaning "%s" missing from document body.'; 87 SAcronymContentMultipleMeanings = 'Warning: Content acronym %s has multiple meanings: %s.'; 88 SAcronymSummaryMultipleMeanings = 'Warning: Summary acronym %s has multiple meanings: %s.'; 89 SAcronymWithDifferentMeaning = 'Warning: Acronym %s has different meaning for content "%s" and for summary "%s".'; 90 SAcronymWithDifferentMeaningCount = 'Warning: Acronym %s has different meaning count for content (%d) and for summary (%d).'; 84 91 SPluralAcronym = 'Note: Acronym %s is defined as plural in document body.'; 92 SPluralAcronymUsed = 'Note: Acronym %s is used as plural in document body.'; 85 93 SSummaryAcronyms = 'Summary acronyms'; 86 94 SContentAcronyms = 'Content acronyms'; 95 SAcronymUsedBeforeDefined = 'Acronym %s used before it was defined.'; 96 97 const 98 MinAcronymLength = 2; 87 99 88 100 { TFormCheck } … … 215 227 var 216 228 Text: string; 217 StartIndex: Integer;218 EndIndex: Integer;229 Index: Integer; 230 State: (stNone, stAcronymUsage, stAcronymDefinition); 219 231 Acronym: string; 232 AcronymCharBefore: Char; 233 AcronymCharAfter: Char; 234 Lines: TStringList; 235 HasUpperCase: Boolean; 236 HasLowerCase: Boolean; 237 I: Integer; 238 J: Integer; 239 Line: string; 220 240 Meaning: string; 221 241 Meaning1: string; … … 224 244 HasMeaning2: Boolean; 225 245 Plural: Boolean; 246 StartIndex: Integer; 247 Acro: TAcronym; 226 248 begin 227 249 AcronymDbContent.Acronyms.Clear; 228 250 251 // Make lowercase lines where all alpha characters are in uppercase 252 // These are usually first level chapter titles or first page text 253 Lines := TStringList.Create; 254 Lines.Assign(MemoDocument.Lines); 255 for I := 0 to Lines.Count - 1 do begin 256 HasLowerCase := False; 257 HasUpperCase := False; 258 Line := Lines[I]; 259 for J := 1 to Length(Line) do begin 260 if IsUppercaseAlpha(Line[J]) then HasUpperCase := True; 261 if IsLowercaseAlpha(Line[J]) then HasLowerCase := True; 262 end; 263 if HasUpperCase and not HasLowerCase then 264 Lines[I] := LowerCase(Lines[I]); 265 end; 266 229 267 // Find acronyms usage in text 230 Text := MemoDocument.Lines.Text;268 Text := Lines.Text; 231 269 Text := StringReplace(Text, #9, ' ', [rfReplaceAll]); 232 270 Text := StringReplace(Text, LineEnding, ' ', [rfReplaceAll]); 233 StartIndex := 1; 271 Index := 1; 272 AcronymCharBefore := ' '; 273 AcronymCharAfter := ' '; 274 State := stNone; 275 StartIndex := 0; 234 276 repeat 235 StartIndex := PosFromIndex('(', Text, StartIndex); 236 if StartIndex <> 0 then begin 237 EndIndex := PosFromIndex(')', Text, StartIndex); 238 if EndIndex <> 0 then begin 239 Acronym := Trim(Copy(Text, StartIndex + 1, EndIndex - StartIndex - 1)); 277 if State = stAcronymUsage then begin 278 if not IsUppercaseAlpha(Text[Index]) then begin 279 if Text[Index] = 's' then begin 280 Acronym := Acronym + Text[Index]; 281 Inc(Index); 282 end; 283 if (Index + 1) < Length(Text) then AcronymCharAfter := Text[Index + 1] 284 else AcronymCharAfter := ' '; 285 State := stNone; 286 287 // Allow plural acronyms with ending 's' character 288 if (Length(Acronym) >= 1) and (Acronym[Length(Acronym)] = 's') then begin 289 Acronym := Copy(Acronym, 1, Length(Acronym) - 1); 290 Plural := True; 291 end else Plural := False; 292 293 // Acronyms should not contain numbers 294 if (Length(Acronym) >= MinAcronymLength) and 295 AllowedSideChar(AcronymCharBefore, AcronymCharAfter) then begin 296 // If plural acronym then try to remove ending 's' character from the meaning 297 if Plural then MemoReport.Lines.Add(Format(SPluralAcronymUsed, [Acronym])); 298 299 Acro := AcronymDbContent.Acronyms.SearchByName(Acronym); 300 if not Assigned(Acro) then begin 301 MemoReport.Lines.Add(Format(SAcronymUsedBeforeDefined, [Acronym])); 302 AcronymDbContent.AddAcronym(Acronym, ''); 303 end; 304 end; 305 end else Acronym := Acronym + Text[Index]; 306 end else 307 if State = stAcronymDefinition then begin 308 if Text[Index] = ')' then begin 240 309 // Allow plural acronyms with ending 's' character 241 310 if (Length(Acronym) >= 1) and (Acronym[Length(Acronym)] = 's') then begin … … 262 331 else AcronymDbContent.AddAcronym(Acronym, Meaning); 263 332 end; 264 end; 333 end else 334 // No acronym inside parenthesis, continue with parsing inside 335 Index := StartIndex + 1; 336 State := stNone; 337 end else begin 338 Acronym := Acronym + Text[Index]; 265 339 end; 266 Inc(StartIndex); 267 end; 268 until StartIndex = 0; 340 end else begin 341 if Text[Index] = '(' then begin 342 State := stAcronymDefinition; 343 Acronym := ''; 344 StartIndex := Index; 345 end else 346 if IsUppercaseAlpha(Text[Index]) then begin 347 State := stAcronymUsage; 348 Acronym := Text[Index]; 349 if (Index - 1) >= 0 then AcronymCharBefore := Text[Index - 1] 350 else AcronymCharBefore := ' '; 351 end; 352 end; 353 Inc(Index); 354 until Index > Length(Text); 355 Lines.Free; 356 end; 357 358 function TFormCheck.AllowedSideChar(Before, After: Char): Boolean; 359 begin 360 Result := ((Before = ' ') or (Before = #10) or (Before = #13) or (Before = ',') or 361 (Before = ';') or (Before = '(') or (Before = ')')) 362 and ((After = ' ') or (After = #10) or (After = #13) or (After = ',') or 363 (After = '.') or (After = ';') or (After = '(') or (After = ')')); 364 269 365 end; 270 366 … … 361 457 end; 362 458 459 function TFormCheck.IsLowercaseAlpha(Text: string): Boolean; 460 var 461 I: Integer; 462 begin 463 I := 1; 464 Result := True; 465 while (I <= Length(Text)) do begin 466 if not (Text[I] in ['a'..'z']) then begin 467 Result := False; 468 Break; 469 end; 470 Inc(I); 471 end; 472 end; 473 363 474 function TFormCheck.IsAlpha(Text: string): Boolean; 364 475 var … … 383 494 end; 384 495 496 function TFormCheck.IsDigit(Text: Char): Boolean; 497 begin 498 Result := Text in ['0'..'9']; 499 end; 500 385 501 procedure TFormCheck.ReportDifferencies; 386 502 var … … 388 504 J: Integer; 389 505 Acronym: TAcronym; 506 Acronym2: TAcronym; 390 507 Meaning: TAcronymMeaning; 391 begin 508 Meaning2: TAcronymMeaning; 509 begin 510 // In content but not in summary 392 511 for I := 0 to AcronymDbContent.Acronyms.Count - 1 do begin 393 512 Acronym := TAcronym(AcronymDbContent.Acronyms[I]); 513 if Acronym.Meanings.Count > 1 then 514 MemoReport.Lines.Add(Format(SAcronymContentMultipleMeanings, [Acronym.Name, Acronym.Meanings.GetNames])); 515 Acronym2 := AcronymDbSummary.Acronyms.SearchByName(Acronym.Name); 516 if not Assigned(Acronym2) then 394 517 for J := 0 to Acronym.Meanings.Count - 1 do begin 395 518 Meaning := TAcronymMeaning(Acronym.Meanings[J]); … … 399 522 end; 400 523 524 // In summary but not in content 401 525 for I := 0 to AcronymDbSummary.Acronyms.Count - 1 do begin 402 526 Acronym := TAcronym(AcronymDbSummary.Acronyms[I]); 527 if Acronym.Meanings.Count > 1 then 528 MemoReport.Lines.Add(Format(SAcronymSummaryMultipleMeanings, [Acronym.Name, Acronym.Meanings.GetNames])); 529 Acronym2 := AcronymDbContent.Acronyms.SearchByName(Acronym.Name); 530 if not Assigned(Acronym2) then 403 531 for J := 0 to Acronym.Meanings.Count - 1 do begin 404 532 Meaning := TAcronymMeaning(Acronym.Meanings[J]); 405 533 if not Assigned(AcronymDbContent.SearchAcronym(Acronym.Name, Meaning.Name, [sfCaseInsensitive])) then 406 534 MemoReport.Lines.Add(Format(SMissingAcronymSummary, [Acronym.Name, Meaning.Name])); 535 end; 536 end; 537 538 // With different meaning 539 for I := 0 to AcronymDbSummary.Acronyms.Count - 1 do begin 540 Acronym := TAcronym(AcronymDbSummary.Acronyms[I]); 541 Acronym2 := AcronymDbContent.Acronyms.SearchByName(Acronym.Name); 542 if Assigned(Acronym2) then begin 543 if (Acronym.Meanings.Count = 1) and (Acronym2.Meanings.Count = 1) then begin 544 Meaning := TAcronymMeaning(Acronym.Meanings[0]); 545 Meaning2 := TAcronymMeaning(Acronym2.Meanings[0]); 546 if Meaning.Name <> Meaning2.Name then 547 MemoReport.Lines.Add(Format(SAcronymWithDifferentMeaning, [Acronym.Name, Meaning.Name, Meaning2.Name])); 548 end else 549 MemoReport.Lines.Add(Format(SAcronymWithDifferentMeaningCount, [Acronym.Name, Acronym.Meanings.Count, Acronym2.Meanings.Count])); 407 550 end; 408 551 end;
Note:
See TracChangeset
for help on using the changeset viewer.