Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix forward SyncTex accuracy in internal browser by providing a range location indication alternative #4194

Merged
merged 8 commits into from
Apr 15, 2024

Conversation

pyk1998
Copy link
Contributor

@pyk1998 pyk1998 commented Mar 8, 2024

This proposed solution for issue #4168 involves implementing a range indicator in the PDF viewer based on the line position in the editor. The solution includes several major modifications:

  • Adding a configuration option to choose the indicator type between indicating a single location or a range.
  • Ignoring the column parameter when invoking the SyncTex binary when indicating a range.
  • Parsing all the SyncTex binary records and extracting the box (rectangle) coordinates.
  • Handling the list of records in the viewer, calculating the rectangular coordinates, and displaying them.
  • Adding CSS animation to show the corresponding area in the PDF.

To use this solution, follow these steps:

  • Uncheck the configuration option latex-workshop.synctex.synctexjs.enabled.
  • Choose the Range option in the latex-workshop.synctex.indicator.type configuration.

By implementing these changes, the PDF viewer will display a range rectangular indicator that corresponds to the selected line in the editor.

@James-Yu
Copy link
Owner

Thanks for the contribution. Before looking into the implementation (which is good, just a few function merges to comply with the practice), may I know if this feature is portable to synctex.js?

@jlelong It looks like the binary is still providing a bit more info about the location over synctex.js, making #4186 valid. What do you think of adopting a priority of execution (binary > javascript) to balance utility (binary) and availability (js as fallback)?

@pyk1998
Copy link
Contributor Author

pyk1998 commented Mar 11, 2024

@James-Yu Thank you for the review. If there's any modification needed, please let me know. I'm very happy to have a chance learning from the community.

I've checked the related code, it looks also possible to apply the same logic to synctex.js.

By default, the forward search in synctex.js also returns a single location:

for (const b of blocks as Block[]) {
// Skip a block if they have boxes inside, or their type is kern or rule.
// See also https://github.com/jlaurens/synctex/blob/2017/synctex_parser.c#L4655 for types.
if (b.elements !== undefined || b.type === 'k' || b.type === 'r') {
continue
}
cBottom = Math.max(b.bottom, cBottom)
const top = b.bottom - b.height
cTop = Math.min(top, cTop)
cLeft = Math.min(b.left, cLeft)
if (b.width !== undefined) {
const right = b.left + b.width
cRight = Math.max(right, cRight)
}
}
return new Rectangle({ top: cTop, bottom: cBottom, left: cLeft, right: cRight })

However, it constains a lot of low-level code handling blocks in synctex file:

const linePageBlocks = pdfSyncObject.blockNumberLine[inputFilePath]
const lineNums = Object.keys(linePageBlocks).map(x => Number(x)).sort( (a, b) => { return (a - b) } )
const i = lineNums.findIndex( x => x >= line )
if (i === 0 || lineNums[i] === line) {
const l = lineNums[i]
const blocks = getBlocks(linePageBlocks, l)
const c = toRect(blocks)
return { page: blocks[0].page, x: c.left + pdfSyncObject.offset.x, y: c.bottom + pdfSyncObject.offset.y, indicator: true }
}
const line0 = lineNums[i - 1]
const blocks0 = getBlocks(linePageBlocks, line0)
const c0 = toRect(blocks0)
const line1 = lineNums[i]
const blocks1 = getBlocks(linePageBlocks, line1)
const c1 = toRect(blocks1)
let bottom: number
if (c0.bottom < c1.bottom) {
bottom = c0.bottom * (line1 - line) / (line1 - line0) + c1.bottom * (line - line0) / (line1 - line0)
} else {
bottom = c1.bottom
}

To me, it is not as intuitive to modify them as simply invoking the binary. I will try to analyze them.

@pyk1998
Copy link
Contributor Author

pyk1998 commented Mar 11, 2024

Having tried to modifed synctex.js with no luck.
Maybe the low-level synctex block handling code seems to be incomplete?

According to the comment, the synctex.js seems not handling all the blocks:

for (const b of blocks as Block[]) {
// Skip a block if they have boxes inside, or their type is kern or rule.
// See also https://github.com/jlaurens/synctex/blob/2017/synctex_parser.c#L4655 for types.

A similar but more complete parser is the one used in SumatraPDF:
https://github.com/sumatrapdfreader/sumatrapdf/blob/85a0fa0f09d729e06c7f6e14bf55445723fe0304/ext/synctex/synctex_parser.c#L3310-L3429

(Note that the latest parser used in https://github.com/jlaurens/synctex/blob/main/synctex_parser.c have changed from these two greatly.)

This caused the record returned from the synctex.js is not enough for viewer showing the range of the forward syntex location.
From my simple opinon, using the binary directly is more convenient and easy to maintenance.

@jlelong
Copy link
Collaborator

jlelong commented Mar 13, 2024

@jlelong It looks like the binary is still providing a bit more info about the location over synctex.js, making #4186 valid. What do you think of adopting a priority of execution (binary > javascript) to balance utility (binary) and availability (js as fallback)?

I agree that we can change the order and put the binary first and only keep the js implementation as a fallback.

Copy link
Owner

@James-Yu James-Yu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for this contribution. Please consider the general requests on code structure.

…x-workshop.synctex.indicator.enabled`.

Added fallback logic in `toPDF` for boolean type of `latex-workshop.synctex.indicator.enabled`.

Extend type `SyncTeXRecordToPDFAll` from base type `SyncTeXRecordToPDF`.

Merged `locateRange` to `locate`.

Remove `SyncTeXRecordToPDFAllList`.

Merged `callSyncTeXToPDFRange` to `callSyncTeXToPDF`.

In `ServerResponse`, added and extended type `SynctexData` from base type `SynctexRangeData`.
@pyk1998
Copy link
Contributor Author

pyk1998 commented Mar 20, 2024

@James-Yu Thank you so much for the detailed and kind advice. I have tried my best to merge the functions and types. However, I found that the forwardSynctex seems a lot different from forwardSynctexRange from both parameters and internal logic. I think we can jut let them separate?

@pyk1998 pyk1998 requested a review from James-Yu March 20, 2024 16:23
@pyk1998
Copy link
Contributor Author

pyk1998 commented Mar 24, 2024

@James-Yu I have also tried to merge forwardSynctexRange with forwardSynctex in viewer in the latest commit. Please kindly review all the refactors.

@James-Yu
Copy link
Owner

Thanks for the changes. Will review soon (but not too soon).

Simplify if-else clauses.

Change rectangle default color.

Add comments.
@pyk1998 pyk1998 requested a review from James-Yu March 25, 2024 06:27
@pyk1998
Copy link
Contributor Author

pyk1998 commented Apr 15, 2024

@James-Yu I think I have changed the code according to the comments. Any further updates?

@James-Yu
Copy link
Owner

Not having time to touch this. There are indeed a few issues with code style, yet I will directly commit to the PR shortly.

@James-Yu James-Yu merged commit 2163ae2 into James-Yu:master Apr 15, 2024
6 of 7 checks passed
@pyk1998
Copy link
Contributor Author

pyk1998 commented Apr 15, 2024

@James-Yu Thank you so much for the abundant and kind work on the code style. I've really got so many lessons to learn from the followed up commits. Thank you again for the maintanence of such great extension, and I am so happy having a chance to participate. Wish you all the best.

James-Yu added a commit that referenced this pull request Apr 16, 2024
commit eca259d
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Mon Apr 15 17:52:06 2024 +0100

    Fix #4233 Cache outdir/auxdir per root file

commit 729fe8a
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Mon Apr 15 13:41:04 2024 +0100

    Fix #4215 Add `tkz-euclide` suggestions, update some others

commit 8abc746
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Mon Apr 15 12:53:34 2024 +0100

    Fix a typing issue

commit a7aa1fb
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Mon Apr 15 12:48:22 2024 +0100

    Version 9.20.0

commit 5e15cab
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Mon Apr 15 12:43:53 2024 +0100

    Prioritize SyncTeX binary over synctex.js

commit 2163ae2
Author: Ken Peng <37787058+pyk1998@users.noreply.github.com>
Date:   Mon Apr 15 18:44:32 2024 +0800

    Fix forward SyncTex accuracy in internal browser by providing a range location indication alternative (#4194)

    * Add forward SyncTex with range location indication.

    * Remain default behavior of using red circle for forward SyncTex.

    * Remove unused column parameter in callSyncTeXToPDFRange.

    * Merged configuration `latex-workshop.synctex.indicator.type` to `latex-workshop.synctex.indicator.enabled`.

    Added fallback logic in `toPDF` for boolean type of `latex-workshop.synctex.indicator.enabled`.

    Extend type `SyncTeXRecordToPDFAll` from base type `SyncTeXRecordToPDF`.

    Merged `locateRange` to `locate`.

    Remove `SyncTeXRecordToPDFAllList`.

    Merged `callSyncTeXToPDFRange` to `callSyncTeXToPDF`.

    In `ServerResponse`, added and extended type `SynctexData` from base type `SynctexRangeData`.

    * Merged `forwardSynctexRange` with `forwardSynctex` in viewer.

    * Indent fixing.

    * Change the enum name.

    Simplify if-else clauses.

    Change rectangle default color.

    Add comments.

    * Code style tweaks

    ---------

    Co-authored-by: James Yu <yujianqiaojames@gmail.com>

commit 68c5e74
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Mon Apr 15 10:55:58 2024 +0100

    Fix #4215 Use `kpsewhich.class.enabled` and `kpsewhich.bibtex.enabled` to control `kpsewhich`

commit afe93c7
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Fri Apr 12 11:03:53 2024 +0100

    Fix #4227 Ignore label defs in `xparse` macros

commit 16b504e
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Thu Apr 11 14:50:40 2024 +0100

    Bump tar from 6.2.0 to 6.2.1 (#4226)

    Bumps [tar](https://github.com/isaacs/node-tar) from 6.2.0 to 6.2.1.
    - [Release notes](https://github.com/isaacs/node-tar/releases)
    - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
    - [Commits](isaacs/node-tar@v6.2.0...v6.2.1)

    ---
    updated-dependencies:
    - dependency-name: tar
      dependency-type: indirect
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit e2a5b60
Author: Jerome Lelong <jerome.lelong@gmail.com>
Date:   Thu Apr 11 08:10:26 2024 +0200

    Update grammar files to jlelong/vscode-latex-basics@0393049

commit 7773d50
Author: Jerome Lelong <jerome.lelong@gmail.com>
Date:   Tue Apr 9 07:18:58 2024 +0200

    Update grammar files to jlelong/vscode-latex-basics@6a16810

commit 0738417
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Thu Apr 4 13:09:40 2024 +0100

    Version 9.19.2

commit 0483b31
Author: James Yu <yujianqiaojames@gmail.com>
Date:   Thu Apr 4 13:08:14 2024 +0100

    Prevent `.aux` and `.out` file changes from triggering auto-build

commit 88c83b2
Author: wasalm <info@andries-salm.com>
Date:   Wed Apr 3 15:21:55 2024 +0200

    Bugfix: Synctex does not work while using vscode in browser (#4220)

    * Bugfix syntex for code-server

    Make synctex work in the code server environment

    * Update latexworkshop.ts

    typo

    * Update latexworkshop.ts

    ---------

    Co-authored-by: James Yu <yujianqiaojames@gmail.com>

commit 14fef41
Author: Jerome Lelong <jerome.lelong@gmail.com>
Date:   Tue Mar 26 21:47:07 2024 +0100

    Update grammar files to jlelong/vscode-latex-basics@70d2764
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants