diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index a82be79aae7..c09f8d7997a 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -37,7 +37,7 @@ jobs: build: strategy: fail-fast: false - matrix: + matrix: # if you change the os version rename all other occurrences os: [ubuntu-22.04, windows-latest, macos-13] include: - os: ubuntu-22.04 @@ -75,7 +75,7 @@ jobs: submodules: 'true' show-progress: 'false' - name: Install pigz and cache (linux) - if: (matrix.os == 'ubuntu-latest') + if: (matrix.os == 'ubuntu-22.04') uses: awalsh128/cache-apt-pkgs-action@latest with: packages: pigz @@ -212,7 +212,7 @@ jobs: get-childitem -Path build/distribution/* | rename-item -NewName {$_.name -replace "${{ steps.gitversion.outputs.AssemblySemVer }}","${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}"} get-childitem -Path build/distribution/* | rename-item -NewName {$_.name -replace "portable","${{ steps.gitversion.outputs.Major }}.${{ steps.gitversion.outputs.Minor }}-portable"} - name: Repack deb file for Debian - if: (matrix.os == 'ubuntu-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') + if: (matrix.os == 'ubuntu-22.04') && (steps.checksecrets.outputs.secretspresent == 'YES') shell: bash run: | cd build/distribution @@ -247,7 +247,7 @@ jobs: # macOS: Negated condition of "Upload to GitHub workflow artifacts store (macOS)" # Reason: We either upload the non-notarized files - or notarize the files later (and upload these later) # needs to be on one line; multi line does not work - if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'ubuntu-latest') || ((matrix.os == 'macos-13') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)))) }} + if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'ubuntu-22.04') || ((matrix.os == 'macos-13') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)))) }} shell: bash run: | rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true @@ -268,7 +268,7 @@ jobs: compression-level: 0 # no compression announce: name: Comment on pull request - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: [build] if: ${{ github.event_name == 'pull_request' }} steps: diff --git a/src/main/java/org/jabref/logic/importer/fileformat/PdfContentImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/PdfContentImporter.java index 14a5b1e6c21..6a8eae4c769 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/PdfContentImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/PdfContentImporter.java @@ -252,16 +252,24 @@ private boolean isFarAway(TextPosition previous, TextPosition current) { return Math.abs(Xgap) > XspaceThreshold && Math.abs(Ygap) > YspaceThreshold; } - private boolean isUnwantedText(TextPosition previousTextPosition, TextPosition textPosition) { + private boolean isUnwantedText(TextPosition previousTextPosition, TextPosition textPosition, + Map lastPositionMap, float fontSize) { + // This indicates that the text is at the start of the line, so it is needed. if (textPosition == null || previousTextPosition == null) { return false; } + // We use the font size to identify titles. Blank characters don't have a font size, so we discard them. + // The space will be added back in the final result, but not in this method. if (StringUtil.isBlank(textPosition.getUnicode())) { return true; } - // The title usually don't in the bottom 10% of a page. - return (textPosition.getPageHeight() - textPosition.getYDirAdj()) - < (textPosition.getPageHeight() * 0.1); + // Titles are generally not located in the bottom 10% of a page. + if ((textPosition.getPageHeight() - textPosition.getYDirAdj()) < (textPosition.getPageHeight() * 0.1)) { + return true; + } + // Characters in a title typically remain close together, + // so a distant character is unlikely to be part of the title. + return lastPositionMap.containsKey(fontSize) && isFarAway(lastPositionMap.get(fontSize), textPosition); } private Optional findLargestFontText(List textPositions) { @@ -271,8 +279,7 @@ private Optional findLargestFontText(List textPositions) { for (TextPosition textPosition : textPositions) { float fontSize = textPosition.getFontSizeInPt(); // Exclude unwanted text based on heuristics - if (isUnwantedText(previousTextPosition, textPosition) || - (lastPositionMap.containsKey(fontSize) && isFarAway(lastPositionMap.get(fontSize), textPosition))) { + if (isUnwantedText(previousTextPosition, textPosition, lastPositionMap, fontSize)) { continue; } fontSizeTextMap.putIfAbsent(fontSize, new StringBuilder()); diff --git a/src/main/java/org/jabref/logic/search/query/SearchToSqlVisitor.java b/src/main/java/org/jabref/logic/search/query/SearchToSqlVisitor.java index e204ea9de78..8805c9b19cc 100644 --- a/src/main/java/org/jabref/logic/search/query/SearchToSqlVisitor.java +++ b/src/main/java/org/jabref/logic/search/query/SearchToSqlVisitor.java @@ -207,6 +207,16 @@ public SqlQueryNode visitComparison(SearchParser.ComparisonContext ctx) { setFlags(searchFlags, REGULAR_EXPRESSION, true, true); } + // field = "" -> should find entries where the field is empty + // field != "" -> should find entries where the field is not empty + if (term.isEmpty()) { + if (searchFlags.contains(NEGATION)) { + searchFlags.remove(NEGATION); + } else { + searchFlags.add(NEGATION); + } + } + return getFieldQueryNode(field.toLowerCase(Locale.ROOT), term, searchFlags); } diff --git a/src/test/java/org/jabref/logic/search/query/SearchQuerySQLConversionTest.java b/src/test/java/org/jabref/logic/search/query/SearchQuerySQLConversionTest.java index 87172feff1d..755171768ec 100644 --- a/src/test/java/org/jabref/logic/search/query/SearchQuerySQLConversionTest.java +++ b/src/test/java/org/jabref/logic/search/query/SearchQuerySQLConversionTest.java @@ -695,6 +695,38 @@ cte0 AS ( ) ) SELECT * FROM cte0 GROUP BY entryid""" + ), + + Arguments.of( + "file = \"\"", + """ + WITH + cte0 AS ( + SELECT main_table.entryid + FROM bib_fields."tableName" AS main_table + WHERE main_table.entryid NOT IN ( + SELECT inner_table.entryid + FROM bib_fields."tableName" AS inner_table + WHERE ( + (inner_table.field_name = 'file') AND ((inner_table.field_value_literal ILIKE ('%%')) OR (inner_table.field_value_transformed ILIKE ('%%'))) + ) + ) + ) + SELECT * FROM cte0 GROUP BY entryid""" + ), + + Arguments.of( + "file != \"\"", + """ + WITH + cte0 AS ( + SELECT main_table.entryid + FROM bib_fields."tableName" AS main_table + WHERE ( + (main_table.field_name = 'file') AND ((main_table.field_value_literal ILIKE ('%%')) OR (main_table.field_value_transformed ILIKE ('%%'))) + ) + ) + SELECT * FROM cte0 GROUP BY entryid""" ) ); }