| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- import App from '../../../base'
- App.controller('PdfSynctexController', function ($scope, synctex, ide) {
- this.cursorPosition = null
- $scope.$watch(
- () => synctex.syncToPdfInFlight,
- value => ($scope.syncToPdfInFlight = value)
- )
- $scope.$watch(
- () => synctex.syncToCodeInFlight,
- value => ($scope.syncToCodeInFlight = value)
- )
- ide.$scope.$on('cursor:editor:update', (event, cursorPosition) => {
- this.cursorPosition = cursorPosition
- })
- $scope.syncToPdf = () => {
- if (this.cursorPosition == null) {
- return
- }
- synctex.syncToPdf(this.cursorPosition).then(highlights => {
- $scope.pdf.highlights = highlights
- })
- }
- ide.$scope.$on('cursor:editor:syncToPdf', $scope.syncToPdf)
- $scope.syncToCode = function () {
- synctex
- .syncToCode($scope.pdf.position, {
- includeVisualOffset: true,
- fromPdfPosition: true,
- })
- .then(function (data) {
- const { doc, line } = data
- ide.editorManager.openDoc(doc, { gotoLine: line })
- })
- }
- })
- App.factory('synctex', function (ide, $http, $q) {
- return {
- syncToPdfInFlight: false,
- syncToCodeInFlight: false,
- syncToPdf(cursorPosition) {
- const deferred = $q.defer()
- const docId = ide.editorManager.getCurrentDocId()
- if (docId == null) {
- deferred.reject()
- return deferred.promise
- }
- const doc = ide.fileTreeManager.findEntityById(docId)
- if (doc == null) {
- deferred.reject()
- return deferred.promise
- }
- let path = ide.fileTreeManager.getEntityPath(doc)
- if (path == null) {
- deferred.reject()
- return deferred.promise
- }
- // If the root file is folder/main.tex, then synctex sees the
- // path as folder/./main.tex
- const rootDocDirname = ide.fileTreeManager.getRootDocDirname()
- if (rootDocDirname != null && rootDocDirname !== '') {
- path = path.replace(RegExp(`^${rootDocDirname}`), `${rootDocDirname}/.`)
- }
- const { row, column } = cursorPosition
- this.syncToPdfInFlight = true
- $http({
- url: `/project/${ide.project_id}/sync/code`,
- method: 'GET',
- params: {
- file: path,
- line: row + 1,
- column,
- clsiserverid: ide.clsiServerId,
- },
- })
- .then(response => {
- this.syncToPdfInFlight = false
- const { data } = response
- return deferred.resolve(data.pdf || [])
- })
- .catch(response => {
- this.syncToPdfInFlight = false
- const error = response.data
- return deferred.reject(error)
- })
- return deferred.promise
- },
- syncToCode(position, options) {
- if (options == null) {
- options = {}
- }
- const deferred = $q.defer()
- if (position == null) {
- deferred.reject()
- return deferred.promise
- }
- // FIXME: this actually works better if it's halfway across the
- // page (or the visible part of the page). Synctex doesn't
- // always find the right place in the file when the point is at
- // the edge of the page, it sometimes returns the start of the
- // next paragraph instead.
- const h = position.offset.left
- // Compute the vertical position to pass to synctex, which
- // works with coordinates increasing from the top of the page
- // down. This matches the browser's DOM coordinate of the
- // click point, but the pdf position is measured from the
- // bottom of the page so we need to invert it.
- let v
- if (
- options.fromPdfPosition &&
- (position.pageSize != null ? position.pageSize.height : undefined) !=
- null
- ) {
- v = position.pageSize.height - position.offset.top || 0 // measure from pdf point (inverted)
- } else {
- v = position.offset.top || 0 // measure from html click position
- }
- // It's not clear exactly where we should sync to if it wasn't directly
- // clicked on, but a little bit down from the very top seems best.
- if (options.includeVisualOffset) {
- v += 72 // use the same value as in pdfViewer highlighting visual offset
- }
- this.syncToCodeInFlight = true
- $http({
- url: `/project/${ide.project_id}/sync/pdf`,
- method: 'GET',
- params: {
- page: position.page + 1,
- h: h.toFixed(2),
- v: v.toFixed(2),
- clsiserverid: ide.clsiServerId,
- },
- })
- .then(response => {
- this.syncToCodeInFlight = false
- const { data } = response
- if (
- data.code != null &&
- data.code.length > 0 &&
- data.code[0].file !== ''
- ) {
- const doc = ide.fileTreeManager.findEntityByPath(data.code[0].file)
- if (doc == null) {
- deferred.reject()
- }
- return deferred.resolve({ doc, line: data.code[0].line })
- } else if (data.code[0].file === '') {
- ide.$scope.sync_tex_error = true
- setTimeout(() => (ide.$scope.sync_tex_error = false), 4000)
- }
- })
- .catch(response => {
- this.syncToCodeInFlight = false
- const error = response.data
- return deferred.reject(error)
- })
- return deferred.promise
- },
- }
- })
|